2011-09-02 250 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; 
}