MySql AES_解密&;AES_加密密钥在PHP中不起作用

MySql AES_解密&;AES_加密密钥在PHP中不起作用,php,mysql,encryption,openssl,Php,Mysql,Encryption,Openssl,在我们的项目中,我们计划将数据以加密格式存储在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_B

在我们的项目中,我们计划将数据以加密格式存储在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-ecb、AES-128-gcm、AES-256-cbc、AES_256-ecb、AES-256-gcm等)。对加密和解密使用相同的模式很重要

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

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

MySQL默认使用aes_128_ecb模式(请参阅)。所以,要加密纯文本的账单。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;
再次注意,要小心正确地传递所有信息。但是,在我的系统上,上面的代码片段不产生任何输出。有什么不对劲吗


在我的系统上运行时,我发现aes-128-ecb不受支持。这并不奇怪,因为aes-128-ecb已经做到了。为了解决这个问题,最好在MySQL端使用其他模式进行加密(有关详细信息,请参阅)。

当使用AES使用一个库进行加密,然后使用另一个库进行解密时,务必确保双方的所有细节都相同。比如说

  • AES有多种模式(例如AES-128-cbc、AES_128-ecb、AES-128-gcm、AES-256-cbc、AES_256-ecb、AES-256-gcm等)。对加密和解密使用相同的模式很重要

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

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

MySQL默认使用aes_128_ecb模式(请参阅)。所以,要加密纯文本的账单。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;
再次注意,要小心正确地传递所有信息。但是,在我的系统上,上面的代码片段不产生任何输出。有什么不对劲吗


在我的系统上运行时,我发现aes-128-ecb不受支持。这并不奇怪,因为aes-128-ecb已经做到了。为了解决这个问题,最好在MySQL端使用其他模式进行加密(有关更多信息,请参阅)。

我们在Mcrypt\u encrypt&Mcrypt\u decrypt中获得了解决方案

MySql: