How to securely generate IV for AES CBC encryption?

I am working on some cryptographic materials.

  • I am using AES 256 with CBC mode
  • I am using OPENSSL

I know the following things (source = wikipedia):

initialization vector should be:

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

My question is how to safely generate IV with OPENSSL and PHP? I know that there is such a function in lib mcrypt ( http://fr2.php.net/manual/fr/function.mcrypt-create-iv.php )

I did not find anything for this with OPENSSL (creating a unique and unpredictable IV).

+6
source share
3 answers

Use openssl_random_pseudo_bytes (most preferably, when the second parameter is set to an existing variable, after which you should verify that it is set to TRUE ). This will generate IV with the corresponding characteristics of randomness.

 $wasItSecure = false; $iv = openssl_random_pseudo_bytes(16, $wasItSecure); if ($wasItSecure) { // We're good to go! } else { // Insecure result. Fail closed, do not proceed. } 

As an alternative, PHP 7 offers random_bytes() , which is much simpler.

+5
source

You can use openssl_random_pseudo_bytes (len, & crypto_stron) .

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

The second parameter & crypto_strong allows you to pass a logical variable that will be set to true or false depending on whether the algorithm used is cryptographically protected. Then you can check this variable and process it correctly if the variable returns false. This should never happen, but if it does, you probably want to know.

Here is an example of proper use:

 $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

+2
source

It’s just more convenient to use the same stuff as Thomas sujested:

 private function genIv() { $efforts = 0; $maxEfforts = 50; $wasItSecure = false; do { $efforts+=1; $iv = openssl_random_pseudo_bytes(16, $wasItSecure); if($efforts == $maxEfforts){ throw new Exception('Unable to genereate secure iv.'); break; } } while (!$wasItSecure); return $iv; } 
+1
source

Source: https://habr.com/ru/post/896466/


All Articles