Qual é o parâmetro "length" do AES EVP_Decrypt?
Isso está vinculado aEVP_DecryptFinal_ex Erro no OpenSSL
Eu estava tentando descobrir por que a descriptografia da AES não funcionaria e finalmente descobri qual é o problema e agora estou procurando alguém para me ajudar a resolvê-lo:)
qui está o código que eu testei (de várias postagens aqui
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
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 patrick immling\n'Doctor'.\n'Doctor' who ?\nPrecisely! 123910!§$§% !%%#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
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 patrick immling\n'Doctor'.\n'Doctor' who ?\nPrecisely! 123910!§$$§% !%%$&$(/=))?=(#ü++Ü**<,.here we go sometimes it i s 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 a n 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;
}
amp;$(/=))?=(#ü++Ü**<,.here we go sometimes it i s 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 a n 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;
}
O que eu não entendo:
O que devo alimentar como o parâmetro "len" para as rotinas openSSL EVP Decrypt Decrypt? o que é essa mágica len = c_len + f_len?
Como devo obter isso no caso de eu receber apenas a cifra com a chave e o iv? Isso sempre deve ser possível, certo? Eu sei que strlen é um péssimo parâmetro, especialmente para o binário, pois a entrada de texto cifrado no EVP Decrypt é binária: então, como devo obter iss
á posso ver que, se eu usar len = strlen (texto cifrado), me der uma resposta errada e o parâmetro sizeof também não for o que retorna 4.
O stderr mostra claramente que o EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH e que eu entendo como todos vocês apontaram que os dados do AES devem ter pedaços de 16 bytes. Então, o que devo mudar para alimentar o comprimento?