7 votes

Erreur de chiffrement et de déchiffrement 0x0407106B avec OpenSSL

J'écris une routine en C qui lit une chaîne base64 avec la clé publique et procède au cryptage d'une chaîne. Je teste également le décryptage de la même chaîne mais j'obtiens l'erreur 0x0407106B lorsque j'essaie de faire le décodage :

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

Voici le code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>

//#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";

// String to encrypt
char *str = "1234";

ERR_load_crypto_strings();  

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_string(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_string(ERR_get_error(), NULL));
    return;
}

/*
 * Show base 64 encrypted string  
 */ 
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 string:%s\n",retencrypted);

/*
 * Now decrypt this very string 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_string(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_string(ERR_get_error(), NULL));
    return;
}

printf("resultDecrypt=%d\ndecrypted string: %s\n",resultDecrypt,decrypted);
BIO_free(bpop);
RSA_free(privKey);
ERR_free_strings();
}

Note : J'ai exporté la clé privée en utilisant

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 cette erreur ?

3voto

Omri Barel Points 4426

Le problème est que vous essayez de décrypter le résultat encodé en base64. Vous devriez essayer de décrypter le résultat du cryptage.

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);

De plus, 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 comme flen ? Il doit s'agir de la longueur de la chaîne (c'est-à-dire 4 ou 5, selon que vous souhaitez ou non chiffrer le caractère nul).

Si vous voulez écrire la chaîne cryptée en ASCII (codée en utilisant base64), c'est très bien. Mais vous devez la décoder avant de la décrypter.

1voto

bobobobo Points 17477

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

Bien que Omri Il est vrai que vous transmettez les mauvaises données, et que vous n'allez crypter qu'un seul octet, mais l'erreur est due au fait que la fonction sizeof( encrypted ) est beaucoup trop grande (2560). En d'autres termes, votre récepteur de données pour RSA_public_encrypt doit être un habitué unsigned char* pointeur, no un 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 ) ;

Remarquez l'erreur qu'Omri a signalée, à savoir que vous avez utilisé PADDING comme première arg à RSA_public_encrypt alors que ce devrait être le DATALEN longueur des données.

Si vous corrigez cela, vous obtiendrez une erreur similaire plus tard avec le décryptage de la clé privée. Corrigez-la et vous serez sur la bonne voie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X