nemenems
nemenems

Reputation: 1092

How to securely generate an IV for AES CBC Encryption?

I work on some crypto stuff.

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

an initalization vector should be:

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).

Upvotes: 11

Views: 24403

Answers (3)

user3641049
user3641049

Reputation: 21

Just more comfortable to use the same stuff that 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;
}

Upvotes: 2

Thomas Pornin
Thomas Pornin

Reputation: 74382

Use openssl_random_pseudo_bytes (most preferably with the second parameter set to an existing variable, which you should then test that it was set to TRUE). This will generate IVs with appropriate randomness characteristics.

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

Alternatively, PHP 7 offers random_bytes() which is much simpler.

Upvotes: 10

techdude
techdude

Reputation: 1334

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:

Upvotes: 3

Related Questions