打开SSL加密PHP

时间:2018-11-30 17:48:53

标签: php openssl

我正在尝试使用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

有什么想法吗?

2 个答案:

答案 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;
}