1

I have following c code snippet that try to encrypt "hello" using AES CBC encryption cipher. but some how, the encryption result from below code (mbedtls), is different from Java code result and online tool result. I'm a c programming language newbie, I tried to google around, and can't figure out where is the problem.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbedtls/aes.h"
#include "mbedtls/base64.h"
#include "mbedtls/md5.h"
#include "mbedtls/cipher.h"

int main() 
{
    unsigned char key[] = "6c74ea86f5c867f1"; 
    unsigned char iv[] = "5e64fe04bfd8363b"; 
    unsigned char input[100] = {0};

    memset(input, 0, 100 );
    strcpy(input, "hello");


    mbedtls_aes_context aes;
    mbedtls_aes_init(&aes); 

    mbedtls_aes_setkey_enc( &aes, key, 128 );
    mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, input, input );

    int i;
    for (i=0; i<100; i++) 
    {
        printf("%x ",input[i]);
    }
    printf("\n");

    size_t outlen=0;
    char *dst = (char *)malloc(sizeof(char)*200);

    mbedtls_base64_encode(dst, 100, &outlen, input, 16);

    printf("cipher is: %s \n", dst);

                        
}

the code above print "cipher is: W9T3jTvbtfYGUZ3yXkQ6wA== ", but the java encrption result using same key and iv is "Fr00ZupbEBVr4gwL/l+G2w==", and so is the result from https://www.devglan.com/online-tools/aes-encryption-decryption

Can some one help me out?

Progman
  • 16,827
  • 6
  • 33
  • 48
fad99daf
  • 13
  • 2
  • Hint: Try decrypting to verify. Are you *sure* you're specifying the IV correctly? That looks like hex encoded, which might not be what that takes. – tadman Dec 22 '22 at 02:58
  • Using `unsigned char input[100] = {0};` sets all the bytes in `input` to zero. Using `memset(input, 0, 100);` afterwards is overkill. – Jonathan Leffler Dec 22 '22 at 04:41

1 Answers1

2

Your code looks almost correct, I think the issue may lie in:

mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, input, input );

Because your input buffer is the same as the output buffer.

Try to use two different buffers (one for the input, and one for the output).

Then look if that solves the problem.

The documentation of mbedtls_aes_crypt_cbc says nothing about overlapping input and output buffers.

Edit:

I think I've found the culprit.

It's an issue I've encountered myself in the past too.

When the input isn't 16 bytes aligned, there are multiple ways to "pad" the input.

In your code, you fill up the buffer with zeros 0 but there are ways to pad the input with something else than 0.

Probably mbedtls has a function that lets you pad your input to an existing standard (the one the website devglan.com uses).

Quoting another answer from a different stackexchange site:

There are multiple methods to pad data, which can completely undermine the compatibility of a given encryption program with others. The most used padding method in symmetric ciphers and mode of operation is certainly PKCS#7.

(emphasis mine)

So you probably want "PKCS#7" padding for your input data.

And, a commentor on an issue said this about using mbedtls_aes_* functions directly:

I should add that it's very likely that you should not be using mbedtls_aes_xxx functions. They're mainly intended as building blocks for higher-level APIs, not for direct use by applications. Hard-coding cryptographic algorithms in application code is a bad idea: If you’re typing the letters A-E-S into your code, you’re doing it wrong.

Which would make sense, as with the mbedtls_cipher_* functions you can specify how to pad the input data (mbedtls_cipher_set_padding_mode which defaults to PKCS#7, by the way).

Bottom line:

I think you should try to solve your problem with mbedtls_cipher_* functions instead of doing it with mbedtls_aes_*.

Marco
  • 7,007
  • 2
  • 19
  • 49
  • I initially tried to use different buffer for input and output like in the mbedtls official document, but it didn't work out. I modified the code to use same buffer for input and output after seeing same examples in github. anyway, the result is same, I think it just doesn't matter. – fad99daf Dec 22 '22 at 03:21
  • @fad99daf Ok, I'm able to reproduce your problem on my machine... I'll have a look. – Marco Dec 22 '22 at 03:27
  • @fad99daf I think I've found the culprit. It's an issue I've encountered myself in the past too. When the input isn't 16 bytes aligned, there are multiple ways to "pad" the input. In your code, you fill up the buffer with zeros `0` but there are ways to pad the input with something else than `0`. Probably mbedtls has a function that lets you pad your input to an existing standard (the one the website devglan.com uses). – Marco Dec 22 '22 at 04:04
  • Thank you, I can get the correct encryption result from using "mbedtls_cipher_*" functions now. – fad99daf Dec 26 '22 at 01:52