Encryption

加密方法的密鑰大小

  • October 11, 2013

PHP 中是否有定義的密鑰大小與“AES_256-CBC”方法一起使用,大小是多少?

一些背景:

我想將加密文本儲存到PostgreSQL數據庫中。發布數據的使用者有一個密鑰(儲存在 db 中),該密鑰附加到庫中硬編碼的通用私鑰。

$key = $genericKey . $userKey;

使用的加密方法是*“AES-256-CBC”*,iv_size 為 16。IV 被添加到加密字元串

$return = $iv.$encrypted

然後將其儲存在數據庫中。

看來,如果我生成一個非常大的通用密鑰,然後用 儲存一些數據$userkey1,然後用 解密它$userkey2,數據就會被解碼。如果我用一個小的通用密鑰和一個小的使用者密鑰重新執行它,它不會被解碼。對我來說,看起來好像大鍵被截斷了。

有人可以確認一下並告訴我最大密鑰大小是多少嗎?確保設置鍵不超過 key_size* 的最佳實踐是什麼,例如:md5($key)因為這會產生“固定”數量的字元。

更新

因為顯然 php 有自己的 AES 實現,這是我在自己的類中實現它的方式:

class Crypto {

function __construct(){
 $this->iv_size = 16;
 $this->sleutel = 'somelongkey';
 $this->encryptionMethod  = 'AES-256-CBC';
}

   private function encrypt($str){
  $sleutel = $this->sleutel . $this->userKey;
  $iv = $this->generateRandomString($this->iv_size);
  $cipher = openssl_encrypt($str, $this->encryptionMethod, $sleutel, 0, $iv);
  return $iv.$cipher;
   }
   public function decrypt($data){
       $iv = substr($data, 0, $this->iv_size);
  $sleutel = $this->sleutel . $this->userKey;

       return openssl_decrypt(substr($data, $this->iv_size), $this->encryptionMethod, $sleutel, 0, $iv);

   }
}

在這段程式碼中,您只需將 userKey 附加到您的“sleutel”(又名密鑰):

$sleutel = $this->sleutel . $this->userKey;

問題是,這樣做可能會導致$sleutel長度超出預期的 256 位(32 字節),或者 - 正如您所遇到的那樣 - 少於預期的 256 位(32 字節/字元)。

正如@CodesInChaos 在他的評論中正確提到的那樣

根據定義,AES-256 使用 256 位或 32 字節的密鑰。不多也不少。

因此,要解決您的問題,您必須確保傳遞給密碼函式的密鑰不超過 32 個字節。

為了實現這一點,您可以簡單地選擇遵循通常的加密路徑,使用(例如)MD5 將您的密鑰$sleutel散列到預期的 256 位長度,如下所示:

$sleutel = md5($this->sleutel . $this->userKey);

或者——如果你喜歡選擇另一個散列和更快的函式——你可以使用PHP 的散列函式,它有多個可用的散列可供選擇,例如(例如)這樣:

$sleutel = hash('ripemd128', $this->sleutel . $this->userKey);

但是……這不是我建議你這樣做的方式!因為,您不想使用像 MD5 這樣的弱散列(已知會發生衝突),而且您肯定也不想將弱的十六進製字元序列提供給您的密碼,是嗎?

我的建議

按照目前的加密標準,我的建議是使用 SHA256 在這種情況下應該使用的方式:

$sleutel = hash('sha256', $this->sleutel . $this->userKey, TRUE);

請注意,第三個參數設置為TRUE,這意味著$sleutel將包含32 個原始字節(= 二進製字元)而不是 64 個人類可讀的十六進製字元。

我相信這將解決您的“短鍵”相關問題,以及任何潛在的“長鍵”問題。

引用自:https://crypto.stackexchange.com/questions/10959