7

As a reference and as continuation to the post: how to use OpenSSL to decrypt Java AES-encrypted data?

I have the following questions.

I am using OpenSSL libs and programming in C for encrypting data in aes-cbc-128. I am given any input binary data and I have to encrypt this.

I learn that Java has a CipherParameters interface to set IV and KeyParameters too.

Is there a way to generate IV and a key using openSSL? In short how could one use in a C program to call the random generator of openSSL for these purposes. Can any of you provide some docs/examples/links on this?

Thanks

Community
  • 1
  • 1
pimmling
  • 483
  • 5
  • 10
  • 19

2 Answers2

15

An AES key, and an IV for symmetric encryption, are just bunchs of random bytes. So any cryptographically strong random number generator will do the trick. OpenSSL provides such a random number generator (which itself feeds on whatever the operating system provides, e.g. CryptGenRandom() on Windows or /dev/random and /dev/urandom on Linux). The function is RAND_bytes(). So the code would look like this:

#include <openssl/rand.h>

/* ... */
unsigned char key[16], iv[16];

if (!RAND_bytes(key, sizeof key)) {
    /* OpenSSL reports a failure, act accordingly */
}
if (!RAND_bytes(iv, sizeof iv)) {
    /* OpenSSL reports a failure, act accordingly */
}
Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
  • Thanks a lot. I am using a linux system, how should I call the dev/urandom here in the code? – pimmling Apr 07 '11 at 13:01
  • @pimmling: you do not use `/dev/urandom`, the implementation of `RAND_bytes()` does it for you. If you use `/dev/urandom` directly (forfeiting portability to the Windows world), then this is just a file (a special file, but seen as a file nonetheless) that you open and read (hence `fopen()`, `fread()` and `fclose()`). Calling `RAND_bytes()` is easier (one function call instead of three) and more portable (OpenSSL will use the proper OS-provided RNG, be it `/dev/urandom` on Linux, or something else on other systems). – Thomas Pornin Apr 07 '11 at 13:17
  • Oh ok. But how do I set a seed value? When I looked at openSSL code, I saw that they set a const string and simply do a RAND_seed(string, sizeof string). Should I do something like this? And these RAND_bytes generate a true random number and not pseudorandom? – pimmling Apr 07 '11 at 13:48
  • 3
    @pimmling: you do not set the seed. The code in OpenSSL will use the OS to get whatever seed it needs whenever it needs it. If `RAND_bytes()` reports an error then it means that it could not get enough seeding material, which means that the _OS itself_ was out of seed, and there is very little that you could have done to avoid that. This will not happen in practice, but if it happens, then you want to abort the application rather than silently using weak random values. Just call `RAND_bytes()`, and abort if that function returns 0. – Thomas Pornin Apr 07 '11 at 14:06
  • @ThomasPornin Hi. Though this question is old, my question http://stackoverflow.com/questions/35681704/how-to-create-a-pem-file-with-aes-key is continuation to similar issue here. Can you please have a look at it. – Madhur Rawat Feb 28 '16 at 17:53
2

Assuming AES-128:

unsigned char key[16];
RAND_bytes(key, sizeof(key));

unsigned char iv[16];
RAND_bytes(iv, sizeof(iv));

The random generator needs to be seeded before using one of those.

  • A quick read on wiki about "random seed" says it is an initial value you provide to start random generator. From Thomas Pornin's msg, I see that OpenSSL picks this seed from /dev/urandom? on linux. How do I then set it with RAND_seed(const void *buf, int num) ??? – pimmling Apr 07 '11 at 13:05
  • #include unsigned char rnd_seed = (unsigned char) time(NULL)); RAND_seed(rnd_seed, sizeof rnd_seed); How about this? – pimmling Apr 07 '11 at 13:59
  • 3
    @pimmling: No, no, a thousand times no. `time(NULL)` does not contain nearly enough entropy - if you do that, your system *will* be trivially insecure. – caf Apr 10 '11 at 12:40