Erreur de chiffrement et de déchiffrement 0x0407106B à l’aide d’OpenSSL

J’écris une routine en C qui lit une chaîne base64 avec la clé publique et encrypte une chaîne. Je teste également le déchiffrement de la même chaîne, mais l’erreur 0x0407106B s’affiche lorsque j’essaie de décoder:

$ openssl errstr 0x0407106B error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02 

Voici le code

 #include  #include  #include  #include  #include  #include  //#define PADDING RSA_PKCS1_OAEP_PADDING #define PADDING RSA_PKCS1_PADDING //#define PADDING RSA_NO_PADDING main() { // public key char *b64_pKey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp2w+8HUdECo8V5yuKYrWJmUbL\ntD6nSyVifN543axXvNSFzQfWNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6\nhsZA81AblAOOXKaUaxvFC+ZKRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68Epn\naOLepTZw+GLTnusQgwIDAQAB\n-----END PUBLIC KEY-----\n"; // private key char *b64priv_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCp2w+8HUdECo8V5yuKYrWJmUbLtD6nSyVifN543axXvNSFzQfW\nNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6hsZA81AblAOOXKaUaxvFC+ZK\nRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68EpnaOLepTZw+GLTnusQgwIDAQAB\nAoGBAKDuq3PikblH/9YS11AgwjwC++7ZcltzeZJdGTSPY1El2n6Dip9ML0hUjeSM\nROIWtac/nsNcJCnvOnUjK/c3NIAaGJcfRPiH/S0Ga6ROiDfFj2UXAmk/v4wRRUzr\n5lsA0jgEt5qcq2Xr/JPQVGB4wUgL/yQK0dDhW0EdrJ707e3BAkEA1aIHbmcVfCP8\nY/uWuK0lvWxrIWfR5MlHhI8tD9lvkot2kyXiV+jB6/gktwk1QaFsy7dCXn7w03+k\nxrjEGGN+kQJBAMuKf55lDtU9K2Js3YSStTZAXP+Hz7XpoLxmbWFyGvBx806WjgAD\n624irwS+0tBxkERbRcisfb2cXmAx8earT9MCQDZuVCpjBWxd1t66qYpgQ29iAmG+\njBIY3qn9uOOC6RSTiCCx1FvFqDMxRFmGdRVFxeyZwsVE3qNksF0Zko0MPKECQCEe\noDV97DP2iCCz5je0R5hUUM2jo8DOC0GcyR+aGZgWcqjPBrwp5x08t43mHxeb4wW8\ndFZ6+trnntO4TMxkA9ECQB+yCPgO1zisJWYuD46KISoesYhwHe5C1BQElQgi9bio\nU39fFo88w1pok23a2CZBEXguSvCvexeB68OggdDXvy0=\n-----END RSA PRIVATE KEY-----\n"; // Ssortingng to encrypt char *str = "1234"; ERR_load_crypto_ssortingngs(); BIO *bpo = BIO_new_mem_buf(b64_pKey, -1); RSA *pubKey = PEM_read_bio_RSA_PUBKEY(bpo, NULL, NULL, NULL); if ( !pubKey ) { printf("%s\n", ERR_error_ssortingng(ERR_get_error(), NULL)); return; } int rsa_length = RSA_size(pubKey); BIO *b64 = NULL; BIO *bmem = NULL; BUF_MEM *bptr = NULL; unsigned char encrypted[2560] = { 0 }; unsigned char retencrypted[2560] = { 0 }; int resultEncrypt = RSA_public_encrypt(PADDING, str, encrypted, pubKey, PADDING); if ( resultEncrypt == -1 ) { printf("%s\n", ERR_error_ssortingng(ERR_get_error(), NULL)); return; } /* * Show base 64 encrypted ssortingng */ b64 = BIO_new((BIO_METHOD *)BIO_f_base64()); BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, encrypted, resultEncrypt); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); memcpy(retencrypted, bptr->data, bptr->length); BIO_free(b64); BIO_free(bpo); RSA_free(pubKey); printf("Encrypted ssortingng:%s\n",retencrypted); /* * Now decrypt this very ssortingng with the private key */ BIO *bpop = BIO_new_mem_buf(b64priv_key, -1); RSA *privKey = PEM_read_bio_RSAPrivateKey(bpop, NULL, NULL, NULL); if ( !privKey ) { printf("%s\n", ERR_error_ssortingng(ERR_get_error(), NULL)); return; } rsa_length = RSA_size(privKey); unsigned char decrypted[2560] = { 0 }; int resultDecrypt = RSA_private_decrypt( RSA_size(privKey), retencrypted, decrypted, privKey, PADDING); if ( resultDecrypt == -1 ) { printf("%s\n", ERR_error_ssortingng(ERR_get_error(), NULL)); return; } printf("resultDecrypt=%d\ndecrypted ssortingng: %s\n",resultDecrypt,decrypted); BIO_free(bpop); RSA_free(privKey); ERR_free_ssortingngs(); } 

Remarque: j’ai exporté la clé privée à l’aide de

 openssl rsa -in rsa_privatekey.pem -check 

et la clé publique:

 openssl rsa -in rsa_privatekey.pem -pubout 

Pourquoi est-ce que je reçois l’erreur?

Le problème est que vous essayez de déchiffrer le résultat codé en base64. Vous devriez essayer de déchiffrer le résultat du chiffrement.

C’est-à-dire au lieu de:

 int resultDecrypt = RSA_private_decrypt( RSA_size(privKey), retencrypted, decrypted, privKey, PADDING); 

Vous devriez appeler:

 int resultDecrypt = RSA_private_decrypt( RSA_size(privKey), encrypted, decrypted, privKey, PADDING); 

En outre, il y a un problème dans l’appel de chiffrement:

 int resultEncrypt = RSA_public_encrypt(PADDING, str, encrypted, pubKey, PADDING); 

Pourquoi passez-vous PADDING en tant que flen ? Cela devrait être la longueur de la chaîne (c’est-à-dire 4 ou 5, selon que vous voulez chiffrer le caractère nul ou non).

Si vous voulez écrire la chaîne chiffrée en ASCII (codé en base64), c’est très bien. Mais vous devez le décoder avant de le déchiffrer.

L’erreur que vous obtenez est que le type de bloc n’est pas 02 .

Bien qu’Omri ait raison de dire que vous transmettez les mauvaises données et que vous n’allez chiffrer qu’un octet, l’erreur provient du fait que la sizeof( encrypted ) est trop importante (2560). En d’autres termes, votre récepteur de données pour RSA_public_encrypt doit être un pointeur unsigned char* RSA_public_encrypt car unsigned char* non unsigned char[2560] , pas un caractère unsigned char[2560] .

Où vous avez

 unsigned char encrypted[2560] = { 0 }; //X 2560?? RSA_public_encrypt fails. 

Vous devriez utiliser

 unsigned char *encrypted = (unsigned char*)malloc( rsa_length ) ; RSA_public_encrypt( DATALEN, (const unsigned char*)str, encrypted, pubKey, PADDING ) ; 

Notez l’erreur que Omri a signalée, à savoir que vous avez utilisé PADDING comme premier argument de RSA_public_encrypt , alors que cela devrait être la longueur des données DATALEN .

Si vous corrigez cela, vous obtiendrez ultérieurement une erreur similaire avec le déchiffrement de la clé privée. Fixez-le et vous êtes sur votre chemin.