【发布时间】:2018-11-17 00:48:12
【问题描述】:
我正在使用 PHP 7.1,正在研究加密/解密主题。我使用这个函数来编码/解码(基于 PHP 的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;
}
当我 enc/dec strig "MyTestPhrase" 时,这两个函数都运行良好。但是当我加密数据然后将其写入 MySQL 表时,解密失败并出现以下错误代码:
error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
我的$original_plaintext 等于bool(false)。
我是这样想的。 AES 适用于块。解密的字符串必须适合阻止长度:解密数据的大小必须是 16 的倍数。如果不是,我们必须激活 PHP 选项,用 0es 填充它。
猜测这个问题可能与 MySQL 数据格式和加密字符串长度有关,但无法捕捉到。
请帮我解决上面发布的问题。
【问题讨论】:
-
只是为了排除这一点。发送到 db 后,您使用的是与加密相同的密钥进行解密吗?
-
根据Encryption and Compression Functions,您需要将列设置为键入`VARBINARY`或
BLOB。你这样做了吗? -
他不应该那样做。他从加密函数中将其作为base64返回。否则很好。
-
@wayneOS,是的,两个都试过了
-
@Joseph_J,是的,我愿意
标签: php mysql encryption aes