1

i am trying to create a simple application that encrypts and decrypts a small file, < 10 bytes. I am using OpenSSL API of C (AES-128 ecb encryption) and i am encountering a strange "bug" when i encrypt a string and save it to a file.

unsigned char buffer[256];
unsigned char rcv[256];
char my_string[]={"123456"};

int bil = aes_encrypt(my_string, strlen(my_string), "1", NULL, buffer);

FILE* fp =fopen("encrypted_file","w");
write(fileno(fp),buffer,bil);
fclose(fp);

aes_decrypt(buffer, bil, "1", NULL, rec);

printf("%s\n",rec); /* Correct: Prints 123456 */

The problem here is that if i read the ciphertext from the file, although it is exactly the one i had previously saved, it does not seem to be decrypted correctly.

FILE* fp =fopen("encrypted_file","r");

int bil = read(fileno(fp),buffer,256); /* The buffer contains the exact cipher that was created by the aes_encrypt in the first place */
fclose(fp);

int y = aes_decrypt(buffer, bil, "1", NULL, rec);

printf("%s\n",rec);  /* Emptry string */

The encryption and decryption functions are shown bellow:

Encryption:

int
aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned   char *key,
unsigned char *iv, unsigned char *ciphertext){
    EVP_CIPHER_CTX* ctx;

    int len;
    int ciphertext_len;

    ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv);
    EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len);

    ciphertext_len = len;
    EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
    ciphertext_len += len;
    EVP_CIPHER_CTX_free(ctx);
    return ciphertext_len;
}`

Decryption:

int
aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext){
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;

    ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv);
    EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);

    plaintext_len = len;

    EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
    plaintext_len += len;

    EVP_CIPHER_CTX_free(ctx);

    plaintext[plaintext_len] = '\0';

    return plaintext_len;
}
  • Don't you need to use `fread`? Sorry, I'm not a C programmer. – Maarten Bodewes Mar 19 '19 at 00:11
  • 3
    I'd guess that it's reading an 128-bit key from your key pointer, not just the "1" you're giving it (=16 bits: the '1' and a 0 byte), so your key is partially based on other data in memory. Try giving it a much larger key, say 16+ characters. (In practice if you want to use a string here you should use a key derivation function or similar to turn your string into a binary key.) Or see what numbers you get from EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length(). – Rup Mar 19 '19 at 00:11
  • 3
    For AES keys you need 16, 24 or 32 bytes. If your input is a password instead of a key then you need PBKDF2 (which is implemented by OpenSSL) or `EVP_BytesToKey`, preferably both should have a 16 byte salt and high iteration count. – Maarten Bodewes Mar 19 '19 at 00:15
  • True! The key was the actual problem! Thank you for your help! – konstantinosAR Mar 19 '19 at 00:22
  • @Rup: Post as an answer. Let OP accept it. – jxh Mar 19 '19 at 00:23
  • @jxh thanks, but Maarten should not me - his comment is much better informed than mine. – Rup Mar 19 '19 at 00:26
  • Hey, it's 4AM around here, you got it right the same time, I was just amending to your comment, you write it :) – Maarten Bodewes Mar 19 '19 at 03:16

0 Answers0