Я написал небольшую программу для шифрования и дешифрования данных с использованием OpenSSL AES 256 CBC, но после расшифровки зашифрованных данных у меня закончились ненужные данные, поэтому в коде должно быть что-то не так, но я не смог понять это, пожалуйста. взгляните на код и скажите, что я сделал не так:
Основная функция:
/* Message to be encrypted */
unsigned char* plaintext =
(unsigned char*)"The quick brown fox jumps over the lazy dog";
EVP_CIPHER_CTX *en, *de;
en = EVP_CIPHER_CTX_new();
de = EVP_CIPHER_CTX_new();
/* 8 bytes to salt the key_data during key generation. This is an example of
compiled in salt. We just read the bit pattern created by these two 4 byte
integers on the stack as 64 bits of contigous salt material -
ofcourse this only works if sizeof(int) >= 4 */
unsigned int salt[] = {12345, 54321};
unsigned char *key_data;
int key_data_len, i;
key_data = (unsigned char*)"01234567890123456789012345678901";
key_data_len = strlen((const char*)key_data);
Encryption AES;
/* gen key and iv. init the cipher ctx object */
if (AES.Init(key_data, key_data_len, (unsigned char *)&salt, en, de)) {
qDebug() << "Couldn't initialize AES cipher ";
}
unsigned char *ciphertext;
int olen, len;
/* The enc/dec functions deal with binary data and not C strings. strlen() will
return length of the string without counting the '\0' string marker. We always
pass in the marker byte to the encrypt/decrypt functions so that after decryption
we end up with a legal C string */
olen = len = strlen((const char*)plaintext)+1;
ciphertext = AES.Encrypt(en, plaintext, &len);
plaintext = (unsigned char*)"";
plaintext = AES.Decrypt(de, ciphertext, &len);
QString s;
QString result = "";
int rev = strlen((const char*)ciphertext);
for ( int i = 0; i<rev; i++)
{
s = QString("%1").arg(ciphertext[i],0,16);
if(s == "0"){
s="00";
}
result.append(s);
}
ui->label_7->setText(result);
rev = len;
result = "";
for ( int i = 0; i<rev; i++)
{
s = QString("%1").arg(plaintext[i],0,16);
if(s == "0"){
s="00";
}
result.append(s);
}
ui->label_8->setText(result);
free(ciphertext);
free(plaintext);
EVP_CIPHER_CTX_free(en);
EVP_CIPHER_CTX_free(de);
Функция инициализации:
int Encryption::Init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx,
EVP_CIPHER_CTX *d_ctx)
{
int i, nrounds = 5;
unsigned char key[32], iv[32];
/*
* Generate key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
* nrounds is the number of times we hash the material. More rounds are more secure but
* slower.
*/
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
if (i != 32) {
QMessageBox::warning(this, tr("Error while generating the key"), tr("The key isn't 256 bit!"));
return -1;
}
EVP_CIPHER_CTX_init(e_ctx);
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_init(d_ctx);
EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
return 0;
}
Функция шифрования:
inline unsigned char* Encryption:: Encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
// max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE bytes
int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
ciphertext = new unsigned char[c_len];
// allows reusing of 'e' for multiple encryption cycles
EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);
/* update ciphertext, c_len is filled with the length of ciphertext generated,
*len is the size of plaintext in bytes */
int encrypted_bytes = 0;
for(int i=0;i<*len/AES_BLOCK_SIZE;++i)
{
EVP_EncryptUpdate(e, ciphertext+encrypted_bytes, &c_len, plaintext+encrypted_bytes, AES_BLOCK_SIZE);
encrypted_bytes += AES_BLOCK_SIZE;
float counter = i , size = *len/AES_BLOCK_SIZE+1;
emit Encryption_Percentage_Changed(counter/size * 100);
}
// update ciphertext with the final remaining bytes
EVP_EncryptFinal_ex(e, ciphertext+*len, &f_len);
*len = *len + f_len;
emit Encryption_Finished();
return ciphertext;
}
Функция дешифрования:
inline unsigned char* Encryption::Decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
// plaintext will always be equal to or lesser than length of ciphertext
int p_len = *len+AES_BLOCK_SIZE, f_len = 0;
plaintext = new unsigned char[p_len];
EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
int decrypted_bytes = 0;
for(int i=0;i<*len/AES_BLOCK_SIZE;++i){
EVP_DecryptUpdate(e, plaintext+decrypted_bytes, &p_len, ciphertext+decrypted_bytes, AES_BLOCK_SIZE);
decrypted_bytes += AES_BLOCK_SIZE;
float counter = i , size = *len/AES_BLOCK_SIZE;
emit Decryption_Percentage_Changed(counter/size * 100);
}
EVP_DecryptFinal_ex(e, plaintext+*len, &f_len);
*len = *len + f_len;
emit Decryption_Finished();
return plaintext;
}
Редактировать: я заменил изображения с реальным кодом.
Любая помощь будет принята с благодарностью.
Заранее спасибо.