2011-09-02 51 views
6

我工作在一些密码的东西。如何安全生成用于AES CBC加密的IV?

  • 我使用AES 256与CBC模式
  • 我使用OpenSSL

我知道以下的事情(源=维基百科):

一个initalization矢量应为:

  • 独特:对于用给定密钥加密的任何消息,不得重复
  • 不可预知的:一个谁观察任意数量的信息和它们的IV的攻击者应该没有信息来预测下一个成功的概率每位大于50%(即从随机区分)

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

我没有找到任何与OPENSSL(生成独特的和不可预测的IV)做到这一点。

+0

您是否正在验证您的密文? –

回答

5

使用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

如何确定IV的合适长度? – foochow

+2

请注意,openssl_random_pseudo_bytes的第二个可选参数是对变量的引用。当生成的字符串被认为是“密码强”时,其值由openssl设置。请参阅http://www.openssl.org/docs/crypto/RAND_bytes.html – dod

+1

正确。第二个参数是通过引用传递的,并且只有在所使用的算法密码强的情况下,该调用才包含true。以一个例子和正确的用法见下面的答案。 – techdude

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

更多信息参见:

1

使用与Thomas相同的东西更加舒适:

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; 
} 
相关问题