Skip to content
Advertisement

can not decrypt a message using openssl CLI, which was encrypted using openssl API

I was using the above code from Linux libcrypto AES-128 CBC Encryption/Decryption works on Ubuntu but not Raspberry Pi

Modified the code slightly here

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>  

unsigned char aes_key[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};

/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);

int main( )
{
    /* Input data to encrypt */
    unsigned char aes_input[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};

    fprintf(stderr,"%sn",SSLeay_version(SSLEAY_VERSION));

    /* Init vector */
    //unsigned char iv[AES_BLOCK_SIZE];
    unsigned char iv[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
    //memset(iv, 0x00, AES_BLOCK_SIZE);

    /* Buffers for Encryption and Decryption */
    unsigned char enc_out[sizeof(aes_input)];
    unsigned char dec_out[sizeof(aes_input)];

    /* AES-128 bit CBC Encryption */
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, sizeof(aes_key)*8, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, sizeof(aes_input), &enc_key, iv,         AES_ENCRYPT);

    FILE *fp = fopen("id_encrypted","w");
    fwrite(enc_out, sizeof(enc_out), 1, fp); // write all the new buffer
    fclose(fp);

    /* AES-128 bit CBC Decryption */
    //memset(iv, 0x00, AES_BLOCK_SIZE); // don't forget to set iv vector again, else you can't decrypt data properly
    //unsigned char iv[AES_BLOCK_SIZE];
    unsigned char iv2[]={0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
    AES_set_decrypt_key(aes_key, sizeof(aes_key)*8, &dec_key); // Size of key is in bits
    AES_cbc_encrypt(enc_out, dec_out, sizeof(aes_input), &dec_key, iv2, AES_DECRYPT);

    /* Printing and Verifying */    
    print_data("n Original ",aes_input, sizeof(aes_input)); // you can not print data as a string, because after Encryption its not ASCII

    print_data("n Encrypted",enc_out, sizeof(enc_out));

    print_data("n Decrypted",dec_out, sizeof(dec_out));

    return 0;
}

void print_data(const char *tittle, const void* data, int len)
{
    printf("%s : ",tittle);
    const unsigned char * p = (const unsigned char*)data;
    int i = 0;

    for (; i<len; ++i)
        printf("%02X ", *p++);

    printf("n");
}

If you run the code, you can see the below output.

OpenSSL 1.1.1 11 Sep 2018

Original : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

Encrypted : C6 A1 3B 37 87 8F 5B 82 6F 4F 81 62 A1 C8 D8 79

Decrypted : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

My objective is to decrypt the encrypted output file [named as id_encrypted in the code] using openssl CLI.

The command that I have used is

openssl enc -d -v -aes-128-cbc -in id_encrypted -out id_decrypted -K "0123456789abcdef" -iv "0123456789abcdef"

but getting below error message and the output file is empty.

bufsize=8192
hex string is too short, padding with zero bytes to length
hex string is too short, padding with zero bytes to length
bad decrypt
139861660053952:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:537:

Can anyone help with why it’s not working ? I guess, the issue is with the openssl command that I am using, since we can see that the code works for both encryption and decryption.

Advertisement

Answer

Don’t write your encryption code this way. You are using the low level AES API which is intended for power users with a very good knowledge of what they are doing. In particular they do not:

  • Perform padding – which is required in most circumstances (and expected during decryption by the OpenSSL CLI)
  • Use optimised and constant time (i.e. the most secure) implementations by default

They are also very easy to misuse and shoot yourself in the foot. For this and the above reasons the low level AES API has been discouraged for a long time by the OpenSSL project team and will be deprecated in the next version of OpenSSL:

https://github.com/openssl/openssl/blob/9ce921f2dacc9f56b8ae932ae9c299670700a297/CHANGES#L394-L413

Instead you should be using the EVP APIs. See this page for example code:

https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption

Aside from this you have some additional problems in the way that you are specifying the key and iv on the OpenSSL CLI. The “-K” argument expects the key in hex. Each hex digit represents 4 bits (not eight). So the key you have given is equivalent to:

01 23 45 67 89 ab cd ef

But what you wanted was:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

There is a similar problem with the IV. So what you really intended is:

$ openssl enc -d -v -aes-128-cbc -in id_encrypted -out id_decrypted -K "000102030405060708090a0b0c0d0e0f" -iv "000102030405060708090a0b0c0d0e0f"

But this still won’t work until you’ve fixed your encryption code to do proper padding.

Edited to add:

You can also use the -nopad option to do decryption without padding. However, this it is still preferable to rewrite your code to not require this.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement