Rya*_*yan 5 php encryption hash aes laravel
今天我了解到"密码"倾向于表示任意数量字符的可记忆字符串,而"密钥"表示高度随机的字符串(基于所使用的加密算法的特定长度).
所以今天我第一次听说了Key推导函数的概念.
我对如何从任意长度的密码(在PHP中)派生32字节密钥感到困惑.
以下方法有效但忽略了 "[盐]应随机生成"的说明(钠也是如此):
$salt = 'this salt remains constant';
$iterations = 10;
$length = 32;
$aesKey = hash_pbkdf2('sha256', $somePasswordOfArbitraryLength, $salt, $iterations, $length, false);
Run Code Online (Sandbox Code Playgroud)
以下方法也有效,但也不是很正确:
$hash = password_hash($somePasswordOfArbitraryLength, PASSWORD_BCRYPT, ['cost' => $iterations]);
$aesKey = substr($hash, -$length);//this smells weird
Run Code Online (Sandbox Code Playgroud)
通过我的所有搜索,我很惊讶我没有在PHP中找到一种"官方"方式来确定性地从密码中获取32字节密钥.
我该怎么办?
PS我在PHP中使用Laravel并希望使用AES-256-CBC加密,如下所示:
$encrypter = new \Illuminate\Encryption\Encrypter($aesKey, 'AES-256-CBC');
$encryptedText = $encrypter->encrypt($text);
Run Code Online (Sandbox Code Playgroud)
Laravel的加密助手(例如Crypt::encryptString('Hello world.')
)似乎不符合我的要求,因为我希望每个用户的数据根据每个人的密码单独加密.
无论我使用哪种密钥派生函数,每次都会产生相同的密钥,因为我将使用对称加密来解密用户使用该密钥加密的字符串.
如果您希望每次解密或加密存储的字符串时都让他们重新发送密码,则必须使用一致的密码哈希并将盐和迭代存储在某处。
如果您使用password_hash函数,由于随机生成的盐,您永远不会得到相同的值。
>>> password_hash('abc', PASSWORD_BCRYPT)
=> "$2y$10$xR8tZQd0ljF5Ks3QrQt7i.vAbv.xVUc97uh.fX4w0mi/A647HlEWS"
>>> password_hash('abc', PASSWORD_BCRYPT)
=> "$2y$10$KzZWeg.o/4TyJVryWrz/oeWQ6VGj0JnPDW.d.Cp0svu8k6qKBcbWu"
Run Code Online (Sandbox Code Playgroud)
您可以通过选项传递盐,但这通过password_hash已被弃用,因此我建议您坚持使用第一个解决方案。
您不需要为每个人使用相同的盐,您可以生成随机盐并将其存储在某个地方,例如用户表。
请记住,使用这种类型的密钥派生,您需要在用户每次更改密码时重新加密所有值。