如何安全地为AES CBC加密生成IV?

时间:2011-09-02 08:10:26

标签: php vector cryptography openssl

我正在研究一些加密的东西。

  • 我使用带有CBC模式的AES 256
  • 我使用OPENSSL

我知道以下事项(来源=维基百科):

初始化矢量应该是:

  • 唯一:不得对使用给定密钥加密的任何邮件重复
  • 不可预测:观察任意数量的消息及其IV的攻击者应该没有信息来预测下一个消息,其成功概率大于每比特50%(即无法区分随机)

我的问题是,如何使用OPENSSL和PHP安全地生成IV?我知道lib mcrypt(http://fr2.php.net/manual/fr/function.mcrypt-create-iv.php

中存在这样的功能

我没有找到任何与OPENSSL一起做的事情(产生独特且不可预测的IV)。

3 个答案:

答案 0 :(得分:9)

使用openssl_random_pseudo_bytes(最好将第二个参数设置为现有变量,然后应测试它是否设置为TRUE)。这将生成具有适当随机性特征的IV。

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

或者,PHP 7提供random_bytes()更简单。

答案 1 :(得分:2)

您可以使用 openssl_random_pseudo_bytes(len,& crypto_stron)

第一个参数是您想要的长度(以字节为单位)。如果您在其中一个开放的ssl方法中使用它,则可以使用函数 openssl_cipher_iv_length(method)来获得所用方法的正确长度。

第二个参数& crypto_strong允许您传入一个布尔变量,该变量将设置为true或false,具体取决于所使用的算法是否为加密安全。然后,如果变量返回false,则可以检查此变量并正确处理它。它应该永远不会发生,但如果确实如此,那么你可能想知道。

以下是正确使用的示例:

$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.");

有关详细信息,请参阅:

答案 2 :(得分:2)

使用托马斯出版的相同内容会更舒服:

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;
}