我正在使用PHP 7.1,研究加密/解密主题。我使用这个函数来加/减(基于PHP' s official doc):
$key = openssl_random_pseudo_bytes(16);
function encryptName($plaintext) {
global $key;
// $plaintext - string which must be encrypted
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );
return $ciphertext;
}
function decryptName($ciphertext) {
global $key;
// $ciphertext - encrypted string
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key,
$options=OPENSSL_RAW_DATA, $iv); // | OPENSSL_ZERO_PADDING
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac)) {
//echo $original_plaintext."\n";
}
echo openssl_error_string();
return $original_plaintext;
}
当我加入/关闭时," MyTestPhrase"两个功能都运作良好。但是,当我加密数据然后在MySQL表中写入时,解密失败并显示以下错误代码:
error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
我的$original_plaintext
等于bool(false)
。
我想是这样的。 AES适用于块。解密后的字符串必须适合阻止lengt:解密数据的大小必须是16到16之多。如果不是,我们必须激活PHP选项,用0填充它。
猜测问题可能出在MySQL数据格式和加密字符串长度上,但无法捕捉到它。
请帮我解决上面发布的问题。
答案 0 :(得分:1)
所以在我的例子中,我使用pseudo_bytes创建了一个base64_encoded字符串。这样你的关键是不变的。您可以创建自己的密钥,但对于此,我们将使用此密钥。 LoPCPKd8iDxHvb8mATzhhg==
接下来,我们将键定义为常量。这可以在脚本的顶部或conf.php文件中完成。
接下来,我们将在您需要密钥的任何地方使用常量值。
像这样:
define("MYKEY_", base64_decode('LoPCPKd8iDxHvb8mATzhhg=='));
function encryptName($plaintext) {
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, MYKEY_, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, MYKEY_, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );
return $ciphertext;
}
function decryptName($ciphertext) {
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, MYKEY_,
$options=OPENSSL_RAW_DATA, $iv); // | OPENSSL_ZERO_PADDING
$calcmac = hash_hmac('sha256', $ciphertext_raw, MYKEY_, $as_binary=true);
if (hash_equals($hmac, $calcmac)) {
//echo $original_plaintext."\n";
}
echo openssl_error_string();
return $original_plaintext;
}