Hello, I tried to replace RSA_sign and RSA_verify with EVP interface but signature verification fails again! Then problem is private key or public key, but how to guess which one? Even if I open public key and private key from file (using bio) signature verification fails.
On Mon, Dec 21, 2009 at 10:32 AM, Davide Simoncelli <netcelli....@gmail.com>wrote: > Hello Stephen, > thank you for your answer. > Two signs (generated with RSA_sign and openssl tool) are different, so I > guess the problem is private key. Private key is generated with openssl > utility and I fill RSA object with PEM_read_RSAPrivateKey function. Is this > OK? > For example: > > Digest to sign: 5E 91 72 1F AA 54 76 67 0A 2D 19 D1 BE D9 B0 26 1A 71 31 51 > > The signature with openssl rsautl is: 49 48 71 BE 27 B8 79 12 FA 64 2B 66 > 4A 79 02 E1 E0 98 40 C9 FA 89 CD 05 E2 BB B5 D6 4A BC 18 5F 4C DE A9 72 2C > 0A C3 D7 FB 59 65 1E 71 B6 46 C2 50 38 4D D8 36 F3 EF 18 08 96 A3 CD 77 55 > 09 30 05 66 96 73 D2 1F 49 CB 1F 2E A2 21 2A 2E 04 9B E9 E9 7F E5 B0 74 96 > 28 02 E0 61 AA B5 E4 8E 71 E7 DF 71 6D 4F D5 78 E8 5E 6F 86 41 1F 0E 5D 7B > 81 E7 2D AB B8 FE 9B FA 2E D0 0C ED 8E AB 21 B6 13 CE 2B 7C F1 CC 78 34 B7 > 62 7A 81 AB 0A 3A DF E4 48 A7 8D 16 64 E5 38 C4 48 28 4E 05 99 CE 48 8A 39 > B9 AC AC A2 A7 FA 78 52 4E EC CE 76 D7 7D CB 7D 66 14 44 DC 0F EB 6F 67 D9 > 35 48 00 85 53 99 3C 3A B4 A5 41 D7 0A 14 D7 7C 30 5E 0F 45 D4 B1 9B 71 4F > B1 76 03 38 96 EF FA 37 3D 8C 8D A3 28 9D 91 C0 E6 5E 32 75 9F B4 87 1F DC > BF 67 58 9A 94 1C 41 15 3C C3 8A 07 31 7D 6C C4 87 F7 AB 75 D2 35 DD 07 96 > AE 82 37 5D ED FA 65 2E 86 30 AA 63 85 57 C7 F8 37 32 51 31 CE 14 E2 7B 91 > 39 2C 75 71 9B C3 90 8B 4E EE 76 48 4E 48 27 CD D1 B2 72 F3 E6 5E 52 42 34 > 54 5A 54 C6 9D 26 DE A0 30 DE CE D2 A4 CD EE AA EF BA 46 0E 08 C5 AC 83 7E > 72 50 0E 40 BA 3E DE 9E 43 14 61 A9 8D 23 14 25 B1 18 6C 7B 69 E5 1C CA 62 > 60 04 1C 80 3A 7A 53 48 64 EF C7 AF F4 F8 A4 CF 3D 03 7B E7 1A 4C A7 84 51 > D4 77 7D 91 8F F9 FF 54 9E 4D 37 7B C1 19 04 28 34 6C A4 30 0F 9F C7 D0 A5 > 23 1E 45 72 A4 BF 2D 87 36 79 CF 77 95 60 7A 65 47 B8 8F C2 56 5A 35 FF 82 > 90 5F A4 3C A8 E0 1E 09 8B 08 B6 44 93 47 E8 3D 23 E2 4A B1 93 D9 78 FB A1 > 05 1E 9F 3A 3C 56 32 E4 E8 ED 04 6C 96 26 81 02 1B 7E 14 10 69 0F F5 4C 27 > CD 05 AB 9C 71 28 C9 D2 31 FA 31 DB BB B8 65 27 BF 37 A7 A8 00 7B 4C 6D 24 > > And if I use this program: > > #include <stdio.h> > #include <stdlib.h> > #include <openssl/evp.h> > #include <openssl/asn1.h> > #include <openssl/x509_vfy.h> > #include <openssl/err.h> > #include <openssl/pem.h> > #include <openssl/ssl.h> > #include <string> > #include <iostream> > #include <stdint.h> > #include "string.h" > > using namespace std; > > void printHex(uint8_t *out, size_t len) > { > uint8_t n; > for(int i = 0; i < len; i++) { > memcpy( &n, &out[i], 1); > printf("%02x ", n); > } > } > > int get_passhphrase(char *buf, int size, int rwflag, void *u) > { > char tmp[] = "mypass"; > int len = strlen(tmp); > memcpy(buf, tmp, len); > return len; > } > > int main(int argc, char *argv[]) > { > ERR_load_crypto_strings(); > OpenSSL_add_all_algorithms(); > // Read the node certificate > FILE *f = fopen("/home/netcelli/certificates/node1/ca-node1-cert.pem", > "r"); > if(f == NULL) { > cout << "Error loading certificate " << endl; > return 1; > } > // Convert PEM format ceritificate into X509 structure > X509 *certificate; > if (!(certificate = PEM_read_X509(f, NULL, NULL, NULL))) { > cout << "Error reading client certificate in file " << > ERR_error_string(ERR_get_error(), NULL) << endl; > fclose(f); > return 1; > } > fclose(f); > // Get the PUBLIC KEY > EVP_PKEY *pubKey = X509_get_pubkey(certificate); > unsigned char *encodedPubKey = NULL; > // Convert it to DER format > int pubKeyLen = i2d_PUBKEY(pubKey, &encodedPubKey); > if (pubKeyLen < 0) { > cout << "Error converting public key to DER format" << endl; > return 1; > } > RSA *rsaPubKey = RSA_new(); > if(d2i_RSA_PUBKEY(&rsaPubKey,(const unsigned char **) &encodedPubKey, > pubKeyLen) == NULL) { > cout << "Error filling RSA object : " << > ERR_error_string(ERR_peek_error(), NULL) << endl; > } > EVP_PKEY_free(pubKey); > f = fopen("/home/netcelli/msgToSign.bin", "r"); > if(f == NULL) { > cout << "Error loading plain-text message" << endl; > return 1; > } > fseek(f, 0, SEEK_END); > int length= ftell (f); > rewind(f); > unsigned char *message = (unsigned char *) malloc(length); > fread (message,1,length,f); > fclose(f); > /** START MESSAGE SIGN **/ > uint8_t * digest = (uint8_t *) malloc(SHA_DIGEST_LENGTH); > SHA1(message, 4, digest); > RSA *rsaPrivKey = RSA_new(); > f = fopen("/home/netcelli/certificates/node1/private/ca-node1-key.pem", > "r"); > if(f == NULL) { > cout << "Cannot open private key file " << endl; > exit(1); > } > ERR_clear_error(); > PEM_read_RSAPrivateKey(f, &rsaPrivKey, get_passhphrase, NULL); > unsigned char *encodedPrivKey = NULL; > // Convert it to DER format > int privKeyLen = i2d_RSAPrivateKey(rsaPrivKey, &encodedPrivKey); > if (privKeyLen < 0) { > cout << "Error converting private key to DER format" << endl; > return 1; > } > int err = ERR_get_error(); > if(err) { > cout << "Unable to decrypt private key file (maybe invalid passphrase?) : " > << ERR_error_string(err, NULL) << endl; > } > unsigned int outLen = RSA_size(rsaPrivKey); > uint8_t *out = (uint8_t *) malloc(outLen); > if(!RSA_sign(NID_sha1, digest, SHA_DIGEST_LENGTH, out, &outLen, > rsaPrivKey)) { > cout << "Error generating RSA sign: " << > ERR_error_string(ERR_get_error(), NULL) << endl; > exit(1); > } > free(digest); > RSA_free(rsaPrivKey); > cout << "Sign: "; printHex(out, outLen); cout << endl; > /** END MESSAGE SIGN **/ > digest = (uint8_t *) malloc(SHA_DIGEST_LENGTH); > // Generate message digest > SHA1(message, 4, digest); > //Verify it > if(!RSA_verify(NID_sha1 ,digest, SHA_DIGEST_LENGTH, out, outLen, > rsaPubKey)) { > cout << "Signature is NOT valid" << endl; > } else { > cout << "Signature is valid" << endl; > } > free(digest); > free(message); > return 0; > } > Signature is:42 db c8 00 99 6e 8c b0 f3 91 5c c4 6a a6 b9 96 1c 4f c6 c1 c3 > cd ad e4 9f a2 6d f3 ad a1 10 4b 02 32 1d 7d c8 0e 5f 34 8f c6 38 e2 2d 19 > 18 ba 26 5f c0 6d 07 38 87 89 ca 4b 16 b1 a4 ef cc 90 d3 7d 45 9d 95 e8 a1 > a5 54 19 8c ed 8c 6b 57 91 3f e9 b3 07 d6 91 69 d7 35 ff 82 98 a2 69 4f 4f > 0b b3 f1 63 30 a0 b7 b9 f7 d0 34 a3 f6 27 0e 15 7d b1 e3 ce 3d 94 f0 da 2b > c1 9f f3 ca 08 2b 9e a1 8e c7 cd f8 d2 f1 76 32 c9 e2 d8 20 14 b0 f4 9d f5 > 2c 7c 8e b1 2a 49 f0 20 6d 7f 81 85 1d a0 2e 31 40 ed 66 43 6b 37 3a 78 8e > 21 3e 16 66 3e 2d 40 9a 19 63 bf 39 3f a9 d7 87 98 f4 30 fc 93 93 f8 97 ca > 60 71 96 b7 c8 64 e0 68 31 42 43 d4 14 8c 0f c9 7e 6c 24 b2 75 b1 91 ac fd > 2b 04 88 bf c9 32 3f 4d ef 27 bd e6 17 24 f6 53 7e dd d2 4d 96 43 d8 19 8b > ee c0 4e 89 c9 9e 0c 08 e7 50 a6 cb 32 f7 e6 3e 2e 0e ee 12 8b ec c3 2a a9 > 37 85 29 2b 59 91 3c f6 89 31 d1 b1 b6 45 4c 80 85 fe 14 1c c8 59 57 0b 9e > bc 71 b7 7c 00 a7 1c 01 4c 3b f4 a1 f2 c4 7d da 56 48 83 ab 9d db fb 1b f4 > 04 05 25 79 28 e1 ae c7 7a ec 70 83 bf 93 f4 a4 61 d0 50 c6 7a 88 cc 74 94 > 71 a6 d8 d8 0e 3d 1c 95 92 3a df 55 00 04 d6 ea 95 70 cc d5 4f 83 a9 28 b9 > d4 3e 27 3e 6c 59 f7 4d 33 ac 3e fe 2c 0d 29 d1 02 cf 25 c6 23 ec 6d 45 de > b3 41 d9 42 01 e4 45 90 54 71 34 ab 67 0d a7 49 8e 65 ae d1 a1 52 e3 7a 32 > f6 4e 27 1e fb 6f 57 0d 12 83 23 04 0b 8f 08 88 c3 df 81 5a 81 da 35 e8 b7 > 84 31 fc f2 b1 85 75 2a d2 4b f6 99 3e 2b 33 37 22 87 a1 5b 43 a2 1e 2e 19 > 54 8b d5 d1 60 bf 69 7b 15 26 eb 63 a5 16 6e ba ca fe e9 b4 7e 02 38 82 36 > 9e 30 a4 4c 86 65 28 5b 88 bf a5 50 dd 98 75 76 > > Why two different signatures? I guess the code above is ok :( > Thank you > > > On Sun, Dec 20, 2009 at 5:12 PM, Dr. Stephen Henson <st...@openssl.org>wrote: > >> On Sun, Dec 20, 2009, Davide Simoncelli wrote: >> >> > Hello, >> > >> > I'm trying to validate a sign of message digest, sent over a protected >> > channel. On one node digest has been generated by using >> RSA_sign(NID_sha1, >> > digest, SHA_DIGEST_LENGTH, out, &outLen, rsaPrivKey), where rsaPrivKey >> is >> > RSA private key extracted from PEM enceded file with >> PEM_read_RSAPrivateKey; >> > on the other node sign is verified with RSA_verify(NID_sha1 ,digest, >> > SHA_DIGEST_LENGTH, out, outLen, rsaPubKey), where rsaPubKey is RSA >> public >> > key extracted from certificate. >> > >> > RSA_verify always returns 0 and I get the following output: >> > Error checking RSA sign: error:0407006A:rsa >> > routines:RSA_padding_check_PKCS1_type_1:block type is not 01 >> > Error checking RSA sign: error:04067072:rsa >> > routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed >> > >> > Received signed digest message is OK and I guess it has PKCS padding >> (Does >> > RSA_sign care about it?). Any idea why does it fails? >> > I also noticed that if I generate sign by using openssl rsautl, sign is >> > different and has different size. >> > >> > I really appreciete your help ;) >> > >> >> Several possibilities, invalid public key used to verify (e.g. doesn't >> match >> private key used to sign) or signature corrupted (not passed as a >> binary string: strlen used for example). >> >> If the digest didn't match you'd get a different error. >> >> You get a different signature with rsautl because it isn't quite the same >> operation. If you use dgst -sign on the data itself (not the digest) you >> get >> the equivalent format. >> >> Steve. >> -- >> Dr Stephen N. Henson. OpenSSL project core developer. >> Commercial tech support now available see: http://www.openssl.org >> ______________________________________________________________________ >> OpenSSL Project http://www.openssl.org >> User Support Mailing List openssl-users@openssl.org >> Automated List Manager majord...@openssl.org >> > >