Exemple OpenSSL C d'AES-GCM utilisant des interfaces EVP
Pour AES-GCM de chiffrement/déchiffrement, j'ai essayé ceci, mais il a un problème.
ctx = EVP_CIPHER_CTX_new();
//Get the cipher.
cipher = EVP_aes_128_gcm ();
#define GCM_IV "000000000000"
#define GCM_ADD "0000"
#define TAG_SIZE 16
#define ENC_SIZE 64
//Encrypt the data first.
//Set the cipher and context only.
retv = EVP_EncryptInit (ctx, cipher, NULL, NULL);
//Set the nonce and tag sizes.
//Set IV length. [Optional for GCM].
retv = EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, strlen((const char *)GCM_IV), NULL);
//Now initialize the context with key and IV.
retv = EVP_EncryptInit (ctx, NULL, (const unsigned char *)keybuf, (const unsigned char *)GCM_IV);
//Add Additional associated data (AAD). [Optional for GCM]
retv = EVP_EncryptUpdate (ctx, NULL, (int *)&enclen, (const unsigned char *)GCM_ADD, strlen(GCM_ADD));
//Now encrypt the data.
retv = EVP_EncryptUpdate (ctx, (unsigned char *)encm, (int *)&enclen, (const unsigned char *)msg, _tcslen (msg) *sizeof(Char));
//Finalize.
retv = EVP_EncryptFinal (ctx, (unsigned char *)encm + enclen, (int *)&enclen2);
enclen += enclen2;
//Append authentication tag at the end.
retv = EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_GET_TAG, TAG_SIZE, (unsigned char *)encm + enclen);
//DECRYPTION PART
//Now Decryption of the data.
//Then decrypt the data.
//Set just cipher.
retv = EVP_DecryptInit(ctx, cipher, NULL, NULL);
//Set Nonce size.
retv = EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, strlen((const char *)GCM_IV), NULL);
//Set Tag from the data.
retv = EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_TAG, TAG_SIZE, (unsigned char *)encm + enclen);
//Set key and IV (nonce).
retv = EVP_DecryptInit (ctx, NULL, (const unsigned char*)keybuf, (const unsigned char *)GCM_IV);
//Add Additional associated data (AAD).
retv = EVP_DecryptUpdate (ctx, NULL, (int *)&declen, (const unsigned char *)GCM_ADD,
strlen((const char *)GCM_ADD));
//Decrypt the data.
retv = EVP_DecryptUpdate (ctx, decm, (int *)&declen, (const unsigned char *)encm, enclen);
//Finalize.
retv = EVP_DecryptFinal (ctx, (unsigned char*)decm + declen, (int *)&declen2);
Ce code fonctionne très bien (avec quelques modifications). Il est de crypter et de décrypter le message.
Le problème est que lorsque le texte chiffré est modifié avant le déchiffrement, il encore déchiffre le texte (à tort).
Selon ma compréhension authentification, de chiffrement, dans de tels cas, il ne devrait pas déchiffrer la modification de chiffrement de textes.
Où je me trompe?
Puis-je obtenir des exemple de AES-GCM à l'aide de vice-président directeur des interfaces de OpenSSL?
source d'informationauteur doptimusprime
Vous devez vous connecter pour publier un commentaire.
Voici un exemple de chiffrer et de déchiffrer 128 octets à chaque appel, la mise à jour pour exemple:
En fin de compte, vous devez vérifier que la valeur de dec_success est 1.
Si vous modifiez le texte CHIFFRÉ, avant de le décrypter, vous devriez obtenir la valeur de 0.
Réponse édité pour la modernité:
Vous devez vérifier la valeur de retour de l'appel à la EVP_DecryptFinal() (ou EVP_DecryptFinal_ex()) afin de déterminer si vous avez réussi à décrypter le texte chiffré.
OpenSSL fournit désormais parfaitement fonctionnel exemple de l'AES GCM, écrit en C. Il inclut même des vecteurs de test. Vous pouvez le trouver ici https://github.com/openssl/openssl/blob/master/demos/evp/aesgcm.c ou de la recherche pour "openssl evp aesgcm.c"
L'original de 5 ans question de, et de ses réponses, montrer le code qui utilise la EVP_*Init() et EVP_*() Api. Ceux-ci ont été obsolète et remplacé par EVP_*Init_ex() et EVP_*Final_ex() "parce qu'ils peuvent réutiliser un contexte existant sans allouer et de libérer de la place sur chaque appel." (openssl citation)
Dans mon expérience, si vous écrivez une fonction wrapper pour ces appels, ne pas appel EVP_EncryptUpdate_ex() avec un NUL et 0 pour l'AAD. Ce qui pourrait avoir changé dans les plus récentes versions d'OpenSSL, mais en 2013, il a causé de chiffrement de l'échec.
Il est assez loin hors de la portée de cette question, mais au cas où il permet à quiconque, en voici un qui fonctionne iOS /Objective-C mise en œuvre qui utilise OpenSSL Api.
OpenSSL a une belle page de wiki sur l'utilisation de l'AES-GCM algorithmes. Les exemples de Code sont également fournis. Le lien vers la page est Authenticated_Decryption_using_Gcm_mode
J'ai suivi le wiki et le déchiffrement AES-GCM. Le segment de Code est copié ci-dessous
Aussi, comme les gens l'a souligné, vous devez vérifier la valeur retournée par EVP_DecryptFinal_ex(). Si votre texte chiffré est un peu modifié, il peut encore être déchiffré, mais la finale retour de la valeur ne sera pas vrai, parce que la balise de l'authentification (ou le mac) ne peut pas être vérifiée.
OpenSSL n'est pas responsable pour l'authentification. Vous devriez vérifier la valeur de retour de
EVP_DecryptFinal
. Si c'est 1 alors la BALISE de l'authentification des données déchiffrées, est égale à la BALISE que vous avez fournis.Si les tags sont différents, alors vous devez jeter les données déchiffrées comme des faux.
Si les balises sont égales, alors les données sont ok.
Parce que l'authentification est progressive, et peut prendre plusieurs appels à la mise à Jour, les données doivent être déchiffrés avant l'authentification peut être effectuée.