MySql AES_DECRYPT & AES_ENCRYPT Key 在 PHP 中不起作用



在我们的项目中,我们计划将数据以加密格式存储在mysql数据库中,我们使用php&MqSql在我们的项目中。Mqsql加密工作良好,我使用以下方法进行Mqsql

INSERT INTO emails  SET email= TO_BASE64(AES_ENCRYPT('selvamani.p','3xY4/xrbFETctQS0Rkd1r6MKS4PUXetmjTeuRHkMt2w=', '44Y9/xrbFETcmQS0'));
SELECT  id, AES_DECRYPT(FROM_BASE64(email), '3xY4/xrbFETctQS0Rkd1r6MKS4PUXetmjTeuRHkMt2w=','44Y9/xrbFETcmQS0') AS decrypt_string  from emails e 

但我们无法解密PHP中的字符串,该字符串由MqSql加密。在php中,我们使用如下

$stringValue = openssl_encrypt($stringValue, $this->cipher_method,$this->encryption_key, $this->options, $this->encryption_iv);    
$stringValue = openssl_decrypt(base64_decode($stringValue), $this->cipher_method, $this->encryption_key, $this->options, $this->encryption_iv);     

当使用AES使用一个库进行加密,然后使用不同的库进行解密时,确保双方的所有细节都相同是很重要的。例如

  • AES有许多模式(例如,AES-128-cbc、AES_128-ebc、AES-128-gcm、AES-256-cbc、AES-256 gcm等(。对加密和解密使用相同的模式是很重要的。

  • 许多AES加密/解密函数允许您传入密码,而不是密钥,并且函数内部从密码派生密钥。然而,当从一个库转到另一个库时,这通常充满了问题,因为内部用于密钥派生的方法在不同的实现之间差异很大。因此,最好直接传递一个密钥(对于您使用的AES模式,长度正确(,而不是传递密码。

  • 加密和解密函数通常期望明文、密文、密钥、iv等输入作为原始字节而不是文本传递。请注意这一点,并确保在需要时传入原始字节。同样,加密和解密函数通常以原始字节产生输出。一定要相应地处理这些问题。

MySQL默认使用aes_128_ecb模式(请参阅https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html)。因此,要加密明文bill.smith@gmail.com'使用MySQL中使用aes_128_ecb模式的密钥F3229A0B371ED2D9441B830D21A390C3,我们可以这样做:

select to_base64(aes_encrypt('bill.smith@gmail.com', UNHEX('F3229A0B371ED2D9441B830D21A390C3')));

请注意,密钥是作为一个十六进制编码的字符串提供的,其长度与正在使用的模式(128字节(相匹配,我们使用UNHEX((将其转换为MySQL aes_encrypt((函数所需的原始字节。aes_encrypt((函数产生原始字节作为其输出,我们使用to_base64((对这些原始字节进行base64编码,以产生可显示的文本。上述语句生成以下base64编码的密文:

oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=

让我们看看我们是否可以使用相同的密钥,在命令行上使用openssl来解密它,并看看是否生成我们开始使用的明文:

echo -n 'oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=' | base64 -d | openssl aes-128-ecb -d -K F3229A0B371ED2D9441B830D21A390C3

再次,请注意确保所有输入都正确传入。上述命令产生:

bill.smith@gmail.com

太好了。我们能够在MySQL中加密一些明文,然后在openssl中进行相反的操作,结果成功了。现在,让我们看看我们是否可以用PHP解密密文。让我们试试这个:

$ciphertextbase64="oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=";
$keyhex='F3229A0B371ED2D9441B830D21A390C3'; 
$ciphertextbytes=base64_decode($ciphertextbase64);
$keybytes=hex2bin($keyhex);
$plaintext = openssl_decrypt($ciphertextbytes, 'aes-128-ecb', $keybytes);
print $plaintext;

再次,请注意为正确传递所有信息而采取的谨慎措施。但是,在我的系统上,上面的代码片段没有产生任何输出。可能出了什么问题?

在我的系统上运行openssl_get_cipher_methods,我发现aes-128-ecb不受支持。这并不奇怪,因为aes-128-ecb有已知的弱点。为了解决这个问题,最好在MySQL端使用其他模式进行加密(请参阅https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html了解更多信息(。

我们在Mcrypt_encrypt&mcrypt_decrypt

MySql:

选择TO_BASE64(AES_ENCRYPT('selvamani','34/xrbFET445QS0'(AS enc

选择AES_DECRYPT(FROM_BASE64("Bdc3RbB4rU3vBrkdIjTFoQ=="(,'34/xrbFET445QS0'(作为解密字符串

PHP:

$val=";selvamani";;$key=";34/xrbFET445QS0";;$pad_value=16-(strlen($val(%16(;$val=str_pad($val,(16*(floor(strlen($val(/16(+1((,chr($pad_value((;$data=Mcrypt_encrypt(Mcrypt_RIJNDAEL_128,$key,$val,Mcrypt_MODE_ECB,Mcrypt_create_iv(Mcrypt_get_iv_size(Mcrypt _RIJNDAE L_128,Mcrypt _MODE_ECB],Mcrypt_DEV_URANDOM((;echo-base64_encode($data(;

$key=";34/xrbFET445QS0";;$val=base64_decode("Bdc3RbB4rU3vBrkdIjTFoQ=="(;$val=mcrypt_decrypt(mcrypt_RIJNDAEL_128,$key,$val,mcrypt_MODE_ECB,mcrypt_create_iv(mcrypt_get_iv_size(mcrypt_RIJNDAEL_128,mcrypt_MODE_EPCB(,mcrypt_DEV_URANDOM(

echo$val;

最新更新