Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can't decrypt the string after I encrypt the string with PolarSSL AES-CBC

I wrote a program to encrypt a string with PolarSSL AES-CBC

this is my code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <polarssl/aes.h>
#include <polarssl/havege.h>

int main()
{
    char buff[2][64] = {"Who can tell me WHY?", ""};
    havege_state hs;
    int retval;
    unsigned char IV[16];

    aes_context enc_ctx;
    aes_context dec_ctx;

    aes_setkey_enc(&enc_ctx, "password", 256);
    aes_setkey_dec(&dec_ctx, "password", 256);

    havege_init(&hs);
    havege_random(&hs, IV, 16);

    //encrypt
    aes_crypt_cbc(&enc_ctx, AES_ENCRYPT, 64, IV, buff[0], buff[1]);
    havege_random(&hs, IV, 16);

    //decrypt
    aes_crypt_cbc(&dec_ctx, AES_DECRYPT, 64, IV, buff[1],buff[0]);

    printf("After decrypt:%s\n", buff[0]);
    return 0;
}

But when I run it, I just got the wrong text after it decrypt.

I don't understand AES algorithm clearly, because my english is very bad, It's too hard for me to read some articles.

-------------------------Added By midCat--------------------------------------------

I followed you advice, and Change me code now I use the same IV and 256-bit key, this is the new code

int main()
{
    char buff[2][64] = {"ABCDEFGHIJKLMN", ""};
    havege_state hs;
    int retval;
    unsigned char IV[16];
    unsigned char IV2[16];
    unsigned char key[32];

    aes_context enc_ctx;
    aes_context dec_ctx;

    havege_init(&hs);
    havege_random(&hs, IV, 16);
    havege_random(&hs, key, 32);
    strncpy(IV, IV2, 16);           //copy IV

    aes_setkey_enc(&enc_ctx, key, 256);
    aes_setkey_dec(&dec_ctx, key, 256);


    //encrypt
    aes_crypt_cbc(&enc_ctx, AES_ENCRYPT, 64, IV, buff[0], buff[1]);
    printf("Before encrypt:%s\n", buff[0]);

    //decrypt
    aes_crypt_cbc(&dec_ctx, AES_DECRYPT, 64, IV2, buff[1],buff[0]);
    printf("After decrypt:%s\n", buff[0]);
    return 0;
}

I compiler it, and run for many times, got the same output:

Before encrypt:ABCDEFGHIJKLMN
After decrypt:ABCDEFGHYC
                        LMN

How to got IV?

like image 838
midCat Avatar asked Dec 03 '25 17:12

midCat


1 Answers

EDIT: As Daniel pointed out in his answer, one big problem is that you are trying to use a random IV to decrypt (which will not give you the results you expect). However, I suggest that you read the rest of this answer as well.

First of all, aes_set_key_enc and aes_set_key_dec do not take passwords as input, they take keys. A key should be a completely random value as long as the key length (a random string of 32 bytes in your case, since you want to use a 256-bit key).

In your case you're calling aes_set_key_enc/aes_set_key_dec with a short password, but telling it that it should expect a 256-bit key, this will lead to these functions using memory outside of your password as part of the key, and will lead to the encryption and decryption keys to be different.

To recap, AES (or any cipher algorithm for that matter) expects random keys, the algorithms themselves have no concept of expanding a password to a key.

If you want to use a password as a key you need some function that expands a non-random password into a pseudo-random key. The only sane way to do this is to use a function that is designed to be cryptographically secure, but also slow, this is to mitigate the risk of brute-force attacks on the password.

Good functions to use are Colin Percivals scrypt, bcrypt or PBKDF2 of which I would recommend scrypt the most.

However, I want to stress that you probably shouldn't be working at this abstraction level at all. The primitives that you are using (block ciphers, CBC-mode) are at a really low abstraction level, and building a cryptosystem using those primitives can be really dangerous. For example you do not use any kind of authentication on your ciphertext, which might open up your implementation to chosen ciphertext attacks.

I think that the best way to if you want to use cryptography in your application is to try to work at a higher abstraction level, for example using Dan Bernsteins excellent NaCl or Googles KeyCzar.

To recap, your specific problem can be solved by using 256-bit keys, but you should think twice about implementing your own cryptosystem at this abstraction level.

like image 168
dnaq Avatar answered Dec 06 '25 06:12

dnaq