Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to securely generate an IV for AES CBC Encryption?

I work on some crypto stuff.

  • I use AES 256 with CBC mode
  • I use OPENSSL

I am aware of the following things (source = wikipedia):

an initalization vector should be:

  • Unique: must not be repeated for any message encrypted with a given key
  • Unpredictable: an attacker who observes any number of messages and their IVs should have no information to predict the next one with probability of success greater than 50% per bit (i.e., indistinguishable from random)

My question is, how to securely generate the IV with OPENSSL and PHP? I know there is such a functionnality in lib mcrypt (https://php.net/manual/en/function.mcrypt-create-iv.php)

I didn't find anything for doing this with OPENSSL (generating unique and unpredictable IV).

like image 893
nemenems Avatar asked Sep 02 '11 08:09

nemenems


People also ask

Is IV necessary for AES encryption?

AES algorithm requires two different parameters for encryption, a key and an initialization vector (IV).

What is IV in AES-CBC?

Initialization vector (IV) An initialization vector (or IV) are used to ensure that the same value encrypted multiple times, even with the same secret key, will not always result in the same encrypted value. This is an added security layer.

Is AES-CBC mode secure?

Although AES-CBC with HMAC authentication is generally considered secure, CBC is potentially vulnerable to padding attacks, such as POODLE. GCM is not. Proton VPN uses AES-GCM in our OpenVPN encryption suite.


1 Answers

You can use openssl_random_pseudo_bytes(len, &crypto_stron).

The first parameter is the length you want in bytes. If you are using this for use in one of the open ssl methods, you can use the function openssl_cipher_iv_length(method) to get the correct length for the method used.

The second parameter, &crypto_strong, allows you to pass in a boolean variable that will be set to true or false depending on whether the algorithm used was cryptographically secure. You can then check this variable and handle it properly if the variable comes back false. It should never happen, but if it does then you will probably want to know.

Here is an example of proper usage:

$method = 'aes-256-cbc';
$ivlen = openssl_cipher_iv_length($method);
$isCryptoStrong = false; // Will be set to true by the function if the algorithm used was cryptographically secure
$iv = openssl_random_pseudo_bytes($ivlen, $isCryptoStrong);
if(!$isCryptoStrong)
    throw new Exception("Non-cryptographically strong algorithm used for iv generation. This IV is not safe to use.");

For more information see:

  • http://php.net/manual/en/function.openssl-random-pseudo-bytes.php
  • http://php.net/manual/en/function.openssl-cipher-iv-length.php
  • http://php.net/manual/en/function.openssl-get-cipher-methods.php
like image 173
techdude Avatar answered Oct 22 '22 03:10

techdude