我正在尝试使用PHP的openssl_encrypt()
函数,但是我的密钥是以十六进制编码的,并且该函数返回错误。使用hex2bin()
函数将密钥转换为二进制时,返回值为乱码的ASCII文本。然后插入openssl_encrypt()
中。我收到错误消息。
define('TEX_ENCRYPTION_KEY', 'hexadecimalkey...');
define('TEX_ENCRYPTION_IV', 'hexadecimalkey...');
$key = hex2bin(TEX_ENCRYPTION_KEY);
$iv = hex2bin(TEX_ENCRYPTION_IV);
$transData = '<Detail>blah blah blah</Detail>';
$alg = 'aes-256-cbc';
$encryptedData = openssl_encrypt(
$transData,
$alg,
$key,
OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING,$iv
);
这将输出错误:
error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:data
not multiple of block length
有什么想法吗?
答案 0 :(得分:1)
尽管它不在official documentation中,但是对于country.kmz
选项的作用in the comments有很好的解释。默认情况下,OpenSSL会将您的纯文本填充为密码块大小的倍数(对于AES-256-CBC,为16字节。)但是,您已禁用了该机制,并且OpenSSL期望您确保数据长度是16的倍数。不是,因此您会收到错误消息“数据不是块长度的倍数”。
解决方案:填充数据或删除该选项!
OPENSSL_ZERO_PADDING
答案 1 :(得分:0)
在与openssl documentation跳舞之后,我有了解决方案,用openssl替换已贬值的Mcrypt函数(openssl_encrypt和openssl_decrypt函数),并使用base64_encode()返回ASCII文本:
//Return encrypted string
public function stringEncrypt ($plainText, $cryptKey = '7R7zX2Urc7qvjhkr') {
$length = 8;
$cstrong = true;
$cipher = 'aes-128-cbc';
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt(
$plainText, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $cryptKey, $as_binary=true);
$encodedText = base64_encode( $iv.$hmac.$ciphertext_raw );
}
return $encodedText;
}
//Return decrypted string
public function stringDecrypt ($encodedText, $cryptKey = '7R7zX2Urc7qvjhkr') {
$c = base64_decode($encodedText);
$cipher = 'aes-128-cbc';
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ivlenSha2len = $ivlen+$sha2len;
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$plainText = openssl_decrypt(
$ciphertext_raw, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);
}
return $plainText;
}