Quel est le paramètre “longueur” de AES EVP_Decrypt?

Ceci est lié à une erreur EVP_DecryptFinal_ex sur OpenSSL

J’essayais de savoir pourquoi le déchiffrement AES ne fonctionnait pas et finalement j’ai trouvé le problème et je cherche maintenant quelqu’un pour m’aider à le résoudre 🙂

Voici le code que j’ai testé avec (de divers messages ici):

#include  #include  #include  #include  int AES_BLOCK_SIZE = 128; int main(int argc, char **argv) { EVP_CIPHER_CTX en; EVP_CIPHER_CTX de; EVP_CIPHER_CTX_init(&en); EVP_CIPHER_CTX_init(&de); const EVP_CIPHER *cipher_type; unsigned char *passkey, *passiv, *plaintxt; char *plain; char *plaintext; unsigned char *ciphertext; int olen, len; int i =0; unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0 }; unsigned char key[]= { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c , 0 }; unsigned char *input = "hi this is pasortingck immling\n'Doctor'.\n'Doctor' who ?\nPrecisely! 123910!§$$§% !%%$&$(/=))?=(#ü++Ü**<,.here we go sometimes it is difficult but 187! 1$5 78@2 14 .TӒ  틪 ձ1z.$ ? U   <y"; printf("AES ALGORITHM FOR 128 bit CBC MODE\n"); cipher_type = EVP_aes_128_cbc(); AES_BLOCK_SIZE = 128; passkey = key; passiv = iv; plain = input; printf("iv="); for(i = 0; i < sizeof iv; i++){ printf("%02x", iv[i]); //printf("key[%d]= %02x\n", i, key[i]); } printf("\n"); printf("key="); for(i = 0; i < sizeof key; i++){ printf("%02x", key[i]); //printf("key[%d]= %02x\n", i, key[i]); } printf("\n"); printf("Initializing AES ALGORITHM FOR CBC MODE..\n"); EVP_EncryptInit_ex(&en, cipher_type, NULL, passkey, passiv); EVP_DecryptInit_ex(&de, cipher_type, NULL, passkey, passiv); olen = len = strlen(input)+1; printf("len value before aes_encrypt \"%d\"\n", len); // max ciphertext len for an bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes int c_len = len + AES_BLOCK_SIZE - 1; int f_len = 0; ciphertext = (unsigned char *)malloc(c_len); /* allows reusing of 'e' for multiple encryption cycles */ if(!EVP_EncryptInit_ex(&en, NULL, NULL, NULL, NULL)){ printf("ERROR in EVP_EncryptInit_ex \n"); return NULL; } if(!EVP_EncryptUpdate(&en, ciphertext, &c_len, plain, len)){ printf("ERROR in EVP_EncryptUpdate \n"); return NULL; } printf("len value after update \"%d\"\n", len); // printf("size of ciphertext after update \"%d\"\n", sizeof(ciphertext)); printf("strlen value of ciphertext after update \"%d\"\n", strlen(ciphertext)); if(!EVP_EncryptFinal_ex(&en, ciphertext+c_len, &f_len)){ printf("ERROR in EVP_EncryptFinal_ex \n"); return NULL; } printf("len value after final \"%d\"\n", len); printf("strlen value of ciphertext after final \"%d\"\n", strlen(ciphertext)); EVP_CIPHER_CTX_cleanup(&en); len = c_len + f_len; printf("len value after aes_encrypt \"%d\"\n", len); //HERE IS THE PROBLEM: IF I USE len= strlen(ciphertext) I GET ERROR //len = strlen(ciphertext); printf("strlen value of ciphertext after aes_encrypt \"%d\"\n", len); int p_len = len; f_len = 0; plaintext = (unsigned char *)malloc(p_len); // memset(plaintext,0,sizeof(plaintext)); if(!EVP_DecryptInit_ex(&de, NULL, NULL, NULL, NULL)){ printf("ERROR in EVP_DecryptInit_ex \n"); return NULL; } EVP_CIPHER_CTX_set_padding(&de, 0); if(!EVP_DecryptUpdate(&de, plaintext, &p_len, ciphertext, len)){ printf("ERROR in EVP_DecryptUpdate\n"); return NULL; } printf("len value after decrypt update \"%d\"\n", len); if(!EVP_DecryptFinal_ex(&de, plaintext+p_len, &f_len)){ printf("ERROR in EVP_DecryptFinal_ex\n"); ERR_print_errors_fp(stderr); return NULL; } EVP_CIPHER_CTX_cleanup(&de); len = p_len + f_len; printf("Decrypted value = %s\n", plaintext); printf("len value after aes_decrypt \"%d\"\n", len); if (strncmp(plaintext, input, olen)) printf("FAIL: enc/dec failed for \"%s\"\n", input); else printf("OK: enc/dec ok for \"%s\"\n", plaintext); // \"%s\"\n printf("\n"); free(ciphertext); free(plaintext); return 0; } 

Ce que je ne comprends pas:

Que dois-je alimenter en tant que paramètre “len” pour les routines openSSL EVP Decrypt? quelle est cette magie len = c_len + f_len?

Comment dois-je l’obtenir si on me donne juste le chiffre avec la clé et le iv? Cela devrait être toujours possible non? Je sais que strlen est un mauvais paramètre, en particulier pour le binary, car l’entrée de texte chiffré dans EVP Decrypt est binary: comment puis-je l’obtenir?

Je peux déjà voir que si j’utilise len = strlen (texte chiffré) me donne une mauvaise réponse et que le paramètre sizeof n’est pas non plus celui car il renvoie 4.

Le stderr montre clairement que l’EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH et ce que je comprends, car vous avez tous fait remarquer que les données AES devraient être de 16 octets. Alors, que dois-je changer pour nourrir la longueur?

Tout d’abord, ne retournez pas NULL depuis main (). Deuxièmement, je l’ai corrigé et annoté afin que vous puissiez voir ce que signifient les variables de longueur. Je pense que l’essentiel, ce qui vous manque, c’est de donner aux fonctions OpenSSL un tampon dans lequel elles peuvent écrire leurs données. Comme beaucoup de fonctions qui prennent un tampon, vous lui donnez une taille et il vous renvoie le nombre d’octets qu’il a réellement écrits dans le tampon. Pourquoi? Parce que vous devez savoir quand votre tampon est plein, ou si vous remplissez votre tampon de manière incrémentielle, vous devez savoir où écrire le bloc de données suivant.

De plus, je pense que vous devriez lire quelques tutoriels sur la façon de travailler avec des données binarys et sur la différence entre elles et une chaîne de style C. Les fonctions OpenSSL EVP fonctionnent avec des données binarys. C’est pourquoi vous devez indiquer à chaque fonction le nombre d’octets de vos données.

 #include  #include  #include  #include  int main(int argc, char **argv) { EVP_CIPHER_CTX en; EVP_CIPHER_CTX de; EVP_CIPHER_CTX_init(&en); EVP_CIPHER_CTX_init(&de); const EVP_CIPHER *cipher_type; unsigned char *passkey, *passiv, *plaintxt; unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; int input_len = 0; unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; unsigned char key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; const char *ssortingng_to_encrypt = "hi this is pasortingck immling\n'Doctor'.\n'Doctor' who ?\nPrecisely! 123910!§$$§% !%%$&$(/=))?=(#ü++Ü**<,.here we go sometimes it is difficult but 187! 1$5 78@2 14 .TӒ  틪 ձ1z.$ ? U