Generating RSA256 Signature in Loadrunner using C language

Hi,

I am using Web/HTTP protocol to run my script. Inorder to launch the application URL i need to pass the JWT token generated using RSA256 alogorithm.

In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

Therefore, a JWT typically looks like the following.

xxxxx.yyyyy.zzzzz

So, i am able to convert the header and Payload to Base64URL encode.  But i am not able to convert the signature.

The signature will be of 

RSASHA256(
  base64UrlEncode(header)   "."  
  base64UrlEncode(payload)   "."  PrivateKEY)

did anyone genereated the key using loadrunner?

  • I have resolved this issue for following below option

    1) In Java its easy to handle or write code related to RSA signature.

    2) We made that java code as a locolhost webservice and we are passing the Payload and Certificate to this service . It will respond back with the JWT token. where we will use it in the next request.

     

  • Hi Team,

    In my project one of the application is using AWS SHA 256 plugin to generate authentication header which consistes of ASC key, date, region and signature. Through Vugen i am able to capture all the values expect signature because it is generating in the same  call which we need to place the header.

    Could you please let us know if any one faced this issue and let me know if any solutions.

  • Hi Nishant,

    We are facing the same challenge, were certian requests should have JWTs embedded. Please can you provide more information on the same?? Perhaps, It would be a great help, if you can provide the scripts(including java  code)

    Cheers,

    x

  • Would you like to share the details of localhost service and java code. I have similar issue while running into vugen.
  • I'm having the same issue as well. Have there been any code examples presented to use as a guide? Would be much appreciated.

  • Hi,

    Below is an example to generate the required signature.

    #include <string.h>
    #include <stdlib.h>
    
    /* 
     * to avoild including lots of openssl header files into loadrunner, we use (void *) to
     * replace openssl types, like RSA* and BIO *.
     *
     * if you want to use other hash types, find its responding value from Openssl github:
     * github.com/.../obj_mac.h
     */
     
    #define NID_md5         		4
    #define NID_sha256  			672
    
    # define X509_FILETYPE_PEM       1
    # define X509_FILETYPE_ASN1      2
    
    
    void *getRSAKey(const char *file1, int type, const char *password)
    {
        void * file = NULL;
        void *rsa;
    	
        file = (void*)BIO_new_file(file1, "r");
    
        if (file == NULL) return 0;
    
        if (type == 0) {
        	rsa=(void*)d2i_RSAPrivateKey_bio(file, NULL);
        } else if (type == 1) {
            if(password)
            	rsa=(void*)PEM_read_bio_RSAPrivateKey(file, NULL, NULL, (void*)password);
            else
            	rsa=(void*)PEM_read_bio_RSAPrivateKey(file, NULL, NULL, NULL);
        }
    
        BIO_free(file);
        return(rsa);
    }
    
    Action()
    {
    unsigned char * input;
    unsigned char * sign;
    unsigned int sign_len;
    int is_valid_sign;
    const char* private_key_file = "01.pem";
    void * private_key;
    int i;
    
    // you can find this file from {loadrunner}\bin
    lr_load_dll("libcrypto-lt-1_1.dll");
    
    input = (unsigned char*)calloc(64,sizeof(unsigned char));
    strcpy((char*)input,"helllllllllo");
    
    private_key = (void*)getRSAKey(private_key_file, X509_FILETYPE_PEM, NULL);
    
    sign = (unsigned char*)calloc(RSA_size(private_key), sizeof(unsigned char));
    RSA_sign(NID_sha256,input, strlen((char*)input), sign, &sign_len, private_key);
    
    
    lr_output_message("input_string = %s\n", input);
    lr_output_message("signed len = %d\n", sign_len);
    lr_output_message("signed string = %s\n", sign);
    
    for (i=0; i<sign_len;   i)
    {
        lr_output_message("%x%x", (sign[i] >> 4) & 0xf, sign[i] & 0xf);
    }
    lr_output_message("\n");
    
    
    return 0;
    }

    this script is based on OpenSSL libraries, which you can find from {loadrunner}\bin.

    the main API used is  RSA_sign, it can also be  used to generate signature with other types of hash.

  • there are lots of libraries provide high level API to do it.

    find it from this page:https://jwt.io/

  • HI ,

     

    I have been struggling with this issue as well. I have tried your approach but RSA_sign is throwing this error:

    Self.c(96): signed error = error:04075070:rsa routines:RSA_sign:digest too big for rsa key

     

    I have tried using both NID_sha256WithRSAEncryption and NID_sha256 and other types as well

     

        success = RSA_sign(NID_sha256WithRSAEncryption,(unsigned char*) input, strlen((char*)input), sign, &sign_len,private_key);
           
        
        errormessage= (char *) malloc (sizeof(char)*200);
        
        ERR_error_string(ERR_get_error(),errormessage);
        
        
        lr_output_message("signed error = %s\n",errormessage );

     

    Any suggestions?

  • Hello,

    JWT token generation could be easily done with DevWeb protocol using load.utils functions.

    let header = { "alg": "HS256", "typ": "JWT" }; let payload = { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }; let secretKey = load.unmask("EaRk2iUyhRPd0NYTzWLEZ4AGG4BAiL3kjpXUDug SXf6cgj4aarCSnmVdew="); let headerBase64 = load.utils.base64Encode(JSON.stringify(header), { base64URL: true, noPadding: true }); let payloadBase64 = load.utils.base64Encode(JSON.stringify(payload), { base64URL: true, noPadding: true }); let stringToSign = headerBase64 "." payloadBase64; let jwtToken = load.utils.hmac(load.HashAlgorithm.sha256, secretKey, stringToSign, load.HashOutputEncoding.base64RawURL); load.log("Generated jwt token: " jwtToken);

     

    Regards,

    Marina