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

sqyvllje  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(528)

我正在使用PHP7.1,学习加密/解密主题。我使用这个函数来enc/dec(基于php的官方文档):

$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数据格式和加密的字符串长度上,但无法捕获它。
请帮我回答上面的问题。

3pmvbmvn

3pmvbmvn1#

所以在我的示例中,我使用伪字节创建了一个base64\编码的字符串。这样你的钥匙是固定的。你可以创建自己的密钥,但对于这个ex,我们将使用这个密钥。 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;
}

相关问题