我需要哪种数据格式来解密存储在MySQL DB中的数据?

时间:2018-06-07 07:41:32

标签: php mysql encryption aes

我正在使用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数据格式和加密字符串长度上,但无法捕捉到它。

请帮我解决上面发布的问题。

1 个答案:

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