AES opera su blocchi di 16 byte. Il EVP_DecryptUpdate()
funzionerà su blocchi di 16. Finché si utilizza EVP_DecryptUpdate()
, si presume che gli sarà dato più dati da decrittografare e si conserverà l'ultimo blocco di dati all'interno del contesto di crypt. Questo perché in modalità CBC ha bisogno del prossimo blocco di cifratura per essere l'IV per il prossimo blocco di decrittografia perché non può prevedere quando ne avrà bisogno per calcolare il padding.
Immagine Wiki
La"lunghezza decrittografata" sarà esattamente un blocco (16 byte) inferiore a quello che gli viene dato per la prima iterazione perché conserva il secondo blocco di dati. Una volta decrittografata la seconda iterazione, emette il blocco 2 e il blocco 3 (32 byte) e mantiene il blocco 4. Estrapolandolo alla fine del file crittografato, ti renderai conto che saresti 1 blocco breve. Una volta che chiami EVP_DecryptFinal
, il blocco finale viene decodificato (il padding viene preso in considerazione se necessario) e restituito al buffer specificato per i 32 blocchi completi (512 byte nell'esempio).
Codice di esempio
char *decrypt (char *key,
char *iv,
char *encryptedData,
int encryptedLength)
{
// Initialisation
EVP_CIPHER_CTX *cryptCtx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(cryptCtx);
int decryptedLength = 0;
int allocateSize = encryptedLength * sizeof(char);
int lastDecryptLength = 0;
char *decryptedData = (char *) malloc (allocateSize);
memset(decryptedData, 0x00, allocateSize);
int decryptResult = EVP_DecryptInit_ex(cryptCtx,
EVP_bf_cbc(), NULL, key, iv);
// EVP_DecryptInit_ex returns 1 if it succeeded.
if (decryptResult == 1)
{
decryptResult = EVP_DecryptUpdate(cryptCtx, decryptedData,
&decryptedLength, encryptedData, encryptedLength);
// Note that EVP_DecryptUpdate will alter the value of the third parameter
// to be equal to the amount of data that was written. This is not always the
// entire length of the decrypted data! To finish the decryption process, use
// EVP_DecryptFinal_ex. This will decrypt any remaining data.
// Cleanup
if (decryptResult == 1)
{
// Stick the final data at the end of the last
// decrypted data.
EVP_DecryptFinal_ex(cryptCtx,
decryptedData + decryptedLength,
&lastDecryptLength);
decryptedLength = decryptedLength + lastDecryptLength;
decryptedData[decryptedLength – 1] = ”;
printf ("Decrypted size: %d\n", decryptedLength);
printf ("Decrypted data: \n%s\n\n", decryptedData);
}
else
{
printf ("EVP_DeccryptUpdate failure.\n");
}
}
else
{
printf ("EVP_DecryptInit_ex failure.\n");
}
EVP_CIPHER_CTX_free(cryptCtx);
EVP_cleanup();
return decryptedData;
}