Tho*_*ams 14 encryption secret-key initialization-vector php-openssl
我即将使用以下脚本来加密和解密某些数据.我正在使用它,因为我当前的加密在我们的新服务器上不起作用.我们目前正在使用mcrypt,所以我想更改为openssl.
在我们的数据库中,我们使用aes加密,它使用128位密钥,所以我知道密钥是什么,但我不知道openssl iv是什么?为什么我需要钥匙和iv.
我即将使用的代码就是这个,我在网站上找到了,因为我不太了解加密.
显然我会修改它,以便将密钥保存在其他地方.
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
else if( $action == 'decrypt' ){
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
$plain_txt = "This is my plain text";
echo "Plain Text = $plain_txt\n";
$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n";
$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n";
if( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";
echo "\n";
Run Code Online (Sandbox Code Playgroud)
vcs*_*nes 17
初始化向量是使CBC(密码块链接)模式中的AES工作的一部分 - IV不是OpenSSL独有的.CBC通过使用当前块对前一个块进行异或操作来工作.第一个块没有先前的块,因此IV用于此目的.
为什么这是必要的,需要了解分组密码的工作原理.如果没有这种链接和IV,我们将选择一种名为ECB或电子代码簿的AES模式.欧洲央行存在弱点,允许选择明文攻击,以及许多其他问题.
我建议花一些时间与CBC初始化向量的最佳实践.错误地使用它们会削弱AES的整体安全性.简短的解释是:
另请注意,此建议仅适用于AES-CBC.如果您曾调查其他AES模式,例如GCM,则不适用.
alb*_*o56 10
假设两个用户有密码“公主”,你用密钥“some-key”对他们进行编码,他们都会有相同的加密结果:
| User | Encrypted password |
|------------|-----------------------|
| a | sN7vIFg= |
| b | sN7vIFg= |
Run Code Online (Sandbox Code Playgroud)
这意味着,如果有人用不同的方式计算出用户a的真实密码是“公主”,而他们的加密密码是“sN7vIFg=”,那么任何拥有加密密码“sN7vIFg=”的用户都可以被视为拥有密码“公主” ”。
但是,如果您对每个都使用随机 IV,那么如果您有权访问加密数据,则更难猜测底层密码。
| User | Encrypted password | IV |
|------------|-----------------------|----------------|
| a | sN7vIFg= | h²ÓIF8]h%L |
| b | BjZAzrA= | VÂøíiøÚØò? |
Run Code Online (Sandbox Code Playgroud)
现在,即使有人可以访问上述数据,他们也无法弄清楚用户 a 和 b 具有相同的密码。
另请参阅“真盐”与“初始化向量”相同吗? .
我想你可能混淆了“散列密钥”和“iv”(天知道我在开始加密时做过)。散列键正是你所做的。对于 iv,每次使用相同密钥进行加密时,您应该使用不同的随机数据。(我的背景:我必须构建一个 pdo 安全会话处理程序来加密/解密会话数据,所以我最终使用 openssl 扩展实现了 AES-256-CBC)
如果有人来这里只是一个小提示。
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
Run Code Online (Sandbox Code Playgroud)
不是生成 iv + 不需要 secret_iv 的正确方法,因为 iv 必须尽可能随机。不要将它(或理解它)与散列相同。
由于您可以访问 openssl 扩展,因此有一种更好/更安全的方式为所选密码生成 iv,openssl 还可以告诉您密码 iv 的正确长度:
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES-256-CBC'));
Run Code Online (Sandbox Code Playgroud)
它将采用二进制格式,因此如果您需要以十六进制形式使用 bin2hex($iv)。如果您需要将生成的 iv 存储在 mysql 中,我以原始格式存储它(字段类型 varbinary,binary 也有效)。
还有一件事。您在 openssl_encrypt 和 _decrypt 中都将 $options 标记设置为 0,这意味着“如果设置为 true 将作为原始输出数据返回,否则返回值是 base64 编码的”。