Rsassa-pss - Openssl

This is a discussion on Rsassa-pss - Openssl ; Hello, I'd like to signing (and verifying) a message using the RSASSA-PSS. This digital signature scheme's following the 'hash-then-sign paradigm. I'm a newbie with openSSL so I'm asking you if there's already a function for my purpose?! RSA_sign() or RSA_padding_add_PKCS1_PSS() ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Rsassa-pss

  1. Rsassa-pss

    Hello,
    I'd like to signing (and verifying) a message using the RSASSA-PSS. This digital signature scheme's following the 'hash-then-sign paradigm.
    I'm a newbie with openSSL so I'm asking you if there's already a function for my purpose?! RSA_sign() or RSA_padding_add_PKCS1_PSS() or ... ? :-/

    I'm playing in the follow way, but something is wrong when I verify the signature. Can anybody help me,plz?
    Do I need any special certificates before use the RSA_verify() function?

    #include
    #include

    #include
    #include
    #include

    #define nr_bits 1024

    void RSA_write_to_file(RSA* rsa, char* filename, int include_private_data)
    {
    FILE* keyfile = fopen(filename,"w");

    fprintf(keyfile,"%d\r\n",include_private_data);

    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->n));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->e));
    if (include_private_data) {
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->d));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->p));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->q));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->dmp1));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->dmq1));
    fprintf(keyfile,"%s\r\n",BN_bn2hex(rsa->iqmp));
    }
    fclose(keyfile);
    }

    RSA* RSA_read_from_file(char* filename)
    {
    RSA* rsa = RSA_new();
    FILE* keyfile = fopen(filename,"r");
    int include_private_data = 0;
    int max_hex_size = (nr_bits / 4) + 1;
    char *buffer = (char*) malloc(max_hex_size);

    fscanf(keyfile,"%d",&include_private_data);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->n, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->e, buffer);

    if (include_private_data) {
    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->d, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->p, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->q, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->dmp1, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->dmq1, buffer);

    fscanf(keyfile,"%s",buffer);
    BN_hex2bn(&rsa->iqmp, buffer);
    }

    free(buffer);

    return rsa;
    }

    void test()
    {
    char* message = "Hello World";

    unsigned char* signature;
    unsigned char* signature1;
    unsigned int slen;
    unsigned int verified;
    unsigned char digest[SHA256_DIGEST_LENGTH];
    unsigned char buffer[256];

    // hashing the message
    SHA256_CTX sha256_ctx = { 0 };
    SHA256_Init(&sha256_ctx);
    SHA256_Update(&sha256_ctx, message, strlen(message));
    SHA256_Final(digest, &sha256_ctx);

    for(int i = 0; i < 32; i++ )
    printf( "%02x", digest[i] );

    printf("\n");


    // Sign a message using private key
    RSA* private_key = RSA_read_from_file("key.pv");
    signature = (unsigned char*) malloc(RSA_size(private_key));

    //RSA_sign(NID_sha256WithRSAEncryption, (unsigned char*) message, strlen(message), signature, &slen, private_key);

    /* apply PSS padding using SHA256 and salt length 20 */
    if ((RSA_padding_add_PKCS1_PSS(private_key, buffer, digest, EVP_sha256(), 20) == NULL))
    {
    printf("Error\n");
    exit(-1);
    }
    if ((RSA_sign(NID_sha256WithRSAEncryption, digest, SHA256_DIGEST_LENGTH, signature, &slen, private_key)) == NULL)
    {
    printf("Error RSA_sign()\n");
    }

    // Verify the message using public key
    RSA* public_key = RSA_read_from_file("key.pb");
    signature1 = (unsigned char*) malloc(RSA_size(public_key));
    //verified = RSA_verify(NID_sha256WithRSAEncryption, (unsigned char*) message, strlen(message), signature, slen, public_key);
    //if (verified == 1)
    // printf(" sign & ver ... ok!\n");
    unsigned char digest1[SHA256_DIGEST_LENGTH];

    SHA256_CTX sha = {0};
    SHA256_Init(&sha);
    SHA256_Update(&sha, message, strlen(message));
    SHA256_Final(digest1, &sha);
    if ((RSA_verify(NID_sha256WithRSAEncryption, digest1, SHA256_DIGEST_LENGTH, signature1, slen, public_key) == NULL))
    printf(" RSA_verify ... failed!\n");
    else
    printf(" ok! \n");
    // verify signature using SHA-256 and salt length 20
    if ((RSA_verify_PKCS1_PSS(public_key, digest, EVP_sha256(), buffer, 20)) == NULL)
    {
    printf("Error\n");
    } else
    printf(" sign & ver ... ok!\n");


    RSA_free(private_key);
    RSA_free(public_key);
    }


    int main()
    {
    RSA *rsa = RSA_generate_key(nr_bits, 3, NULL, NULL);

    RSA_write_to_file(rsa, "key.pv", 1);
    RSA_write_to_file(rsa, "key.pb", 0);

    test();

    RSA_free(rsa);


    printf( "\n Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();

    return 0;
    }

  2. Re: Rsassa-pss

    I've found out my mistake: Even in the verify function I need that:
    signature = (unsigned char*) malloc(RSA_size(private_key));

    That's bad 'cos seems I almost need the private key (or the dimension) when I verify!

    BTW...I think I've made another mistake: i'm double hashing the message. in fact, RSA computes signatures over a chunk of data by first cryptographically hashing the data to obtain a digest value. This digest and the signer's private key are then used as input to the signing process.

    int RSA_sign(int type, unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa)

    where 'type' is the message digest algorithm that obtains the cryptographic hash of the data to be signed.

    so, Am i right? can somebody help me, plz

+ Reply to Thread