加密方法的密鑰大小
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 個人類可讀的十六進製字元。我相信這將解決您的“短鍵”相關問題,以及任何潛在的“長鍵”問題。