Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Signing and verifying messages with RSASSA-PSS.

3,830 views
Skip to first unread message

Morris

unread,
Aug 27, 2008, 7:55:41 AM8/27/08
to
Hi everybody,

I'm currently in some kind of a dead-end and hope that someone here
can help me.
I want to use the crypto library of OpenSSL to sign and verify
messages using RSASSA-PSS as specified in RSA PKCS#1.

The problem is, that whenever I sign a message and try to verfiy it,
the verification always fails.
I have a test function which does nothing more than sign a message and
verify it imediatly afterwards.
The actual input data of the test function is an unsigned char array
of size 302 and a 2048 bit RSA key in DER format. The output of the
sign function should be 256 bytes long.

Can anybody spot some obvious mistakes? The PSS functions are
unfortunately very poorly documented :(

Regards
Morris

The implementations of the sign, verify and test functions look like
this:

#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/sha.h>

void sign(unsigned char* output, unsigned char* input, int
inputLength, const unsigned char* key, int keyLength)
{
// temp buffer
unsigned char buffer[256];

// apply SHA-1 hash function
unsigned char hashed[EVP_sha1()->md_size];
SHA_CTX sha_ctx;
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, input, inputLength);
SHA1_Final(hashed, &sha_ctx);

// apply PSS padding using SHA-1 and salt length 20
RSA *rsa = d2i_RSAPrivateKey(NULL, &key, keyLength);
RSA_padding_add_PKCS1_PSS(rsa, buffer, hashed, EVP_sha1(), 20);

// encrypt hashed and padded signature
RSA_private_encrypt(256, buffer, output, rsa, RSA_NO_PADDING);
}

int verify(unsigned char* input, const unsigned char* key, int
keyLength)
{
// temp buffer
unsigned char buffer[256];

// apply SHA-1 hash function
unsigned char hashed[EVP_sha1()->md_size];
SHA_CTX sha_ctx;
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, input, 256);
SHA1_Final(hashed, &sha_ctx);

// decrypt signature
RSA* rsa = d2i_RSAPrivateKey(NULL, &key, keyLength);
RSA_public_decrypt(256, input, buffer, rsa, RSA_NO_PADDING);

// verify signature using SHA-1 and salt length 20
return RSA_verify_PKCS1_PSS(rsa, hashed, EVP_sha1(), buffer, 20);
}

int test(unsigned char* input, int inputLength, const unsigned char*
key, int keyLength)
{
unsigned char signature[256];

sign(signature, input, inputLength, key, keyLength);

if(verify(signature, key, keyLength))
{
printf("verified!");
}
else
{
printf("not verified!");
}
}

Morris

unread,
Aug 29, 2008, 2:01:55 AM8/29/08
to
Hi again,

> I'm currently in some kind of a dead-end and hope that someone here
> can help me.
> I want to use the crypto library of OpenSSL to sign and verify
> messages using RSASSA-PSS as specified in RSA PKCS#1.

I've just found my misconception in the verify function. Everything is
working as intended now.
In the case that somebody is interested, see the new code below.

Regards
Morris

#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/sha.h>

void sign(unsigned char* output, unsigned char* input, int
inputLength, const unsigned char* key, int keyLength)
{
// temp buffer
unsigned char buffer[256];

// apply SHA-1 hash function
unsigned char hashed[EVP_sha1()->md_size];
SHA_CTX sha_ctx;
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, input, inputLength);
SHA1_Final(hashed, &sha_ctx);

// apply PSS padding using SHA-1 and salt length 20
RSA *rsa = d2i_RSAPrivateKey(NULL, &key, keyLength);
RSA_padding_add_PKCS1_PSS(rsa, buffer, hashed, EVP_sha1(), 20);

// encrypt hashed and padded signature
RSA_private_encrypt(256, buffer, output, rsa, RSA_NO_PADDING);
}

int verify(unsigned char* signature, unsigned char* input, int


inputLength, const unsigned char* key, int keyLength)
{
// temp buffer
unsigned char buffer[256];

// apply SHA-1 hash function
unsigned char hashed[EVP_sha1()->md_size];
SHA_CTX sha_ctx;
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, input, inputLength);
SHA1_Final(hashed, &sha_ctx);

// decrypt signature


RSA* rsa = d2i_RSAPrivateKey(NULL, &key, keyLength);

RSA_public_decrypt(256, signature, buffer, rsa, RSA_NO_PADDING);

// verify signature using SHA-1 and salt length 20
return RSA_verify_PKCS1_PSS(rsa, hashed, EVP_sha1(), buffer, 20);
}

int test(unsigned char* input, int inputLength, const unsigned char*
key, int keyLength)
{
unsigned char signature[256];

sign(signature, input, inputLength, key, keyLength);

if(verify(signature, input, inputLength, key, keyLength))

bdoy...@gmail.com

unread,
Sep 18, 2017, 10:44:30 AM9/18/17
to
Hi Morris,

I'm working on something similar at the moment but with SHA256.

I was wondering about the salt on this method
RSA_verify_PKCS1_PSS(rsa, hashed, EVP_sha1(), buffer, 20);

You use 20, what does that signify? I can't seem to find any docs to explain the options to pass here.
The sample code i found used -2. The server I am trying to verify is using 32bits but not sure how that translates to what to pass in the above method.

Thanks,
B

fred...@cadete.eu

unread,
Jun 5, 2018, 7:52:31 AM6/5/18
to
On Friday, August 29, 2008 at 8:01:55 AM UTC+2, Morris wrote:
> Hi again,
>
...
> void sign(unsigned char* output, unsigned char* input, int
> inputLength, const unsigned char* key, int keyLength)
> {
...
> // encrypt hashed and padded signature
> RSA_private_encrypt(256, buffer, output, rsa, RSA_NO_PADDING);
> }
>
> int verify(unsigned char* signature, unsigned char* input, int
> inputLength, const unsigned char* key, int keyLength)
> {
...
> RSA_public_decrypt(256, signature, buffer, rsa, RSA_NO_PADDING);

Thanks for the example!
Just a note: This is not conformant to RSA signing. For that, you should *decrypt* when signing and *encrypt* when verifying.
With that inversion, this example will work correctly when interacting with other tools (e.g. sign with openssl dgst -sign, decrypt with this C code).

arthur....@unumotors.com

unread,
May 21, 2019, 12:28:30 PM5/21/19
to
I have just tried this. I was testing/validating against a MIFARE SAM AV2. I got it to succeed only when I changed RSA_NO_PADDING -> RSA_PKCS1_PSS_PADDING. Also I confirm that RSA_public_decrypt(256, signature, signedDataCryptogram, key, RSA_PKCS1_PSS_PADDING); decrypt is necessary.

social...@gmail.com

unread,
Apr 3, 2020, 3:07:19 PM4/3/20
to
I have the same problem anyone know how to solve this?
https://jazzhealthy.com

social...@gmail.com

unread,
Apr 5, 2020, 9:14:47 AM4/5/20
to
Check your website
https://ketodiets2020.com
0 new messages