首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySql AES_DECRYPT & AES_ENCRYPT Key不适用于PHP

MySql AES_DECRYPT & AES_ENCRYPT Key不适用于PHP
EN

Stack Overflow用户
提问于 2021-05-28 04:28:33
回答 2查看 1K关注 0票数 1

在我们的项目中,我们计划将数据以加密格式存储在mysql数据库中,我们在项目中使用了php和MqSql。Mqsql加密工作正常,我在MqSql中使用了下面的方法

代码语言:javascript
复制
 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中,我们如下所示

代码语言:javascript
复制
 $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);     
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-28 13:37:53

当使用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模式(参见https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html)。因此,要用密钥bill.smith@gmail.com在MySQL中使用aes_128_ecb模式加密纯文本“aes_128_ecb”,我们可以这样做:

代码语言:javascript
复制
 select to_base64(aes_encrypt('bill.smith@gmail.com', UNHEX('F3229A0B371ED2D9441B830D21A390C3')));

请注意,对于所使用的模式(128个字节),键是作为十六进制编码的字符串提供的,并且我们使用UNHEX()将其转换为MySQL aes_encrypt()函数所要求的原始字节。aes_encrypt()函数生成原始字节作为其输出,我们使用to_base64()来对这些原始字节进行编码以生成可显示的文本。上面的语句生成以下base64 64编码的密文:

代码语言:javascript
复制
oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=

让我们看看是否可以使用命令行上的openssl使用相同的密钥对其进行解密,并查看是否生成我们开始时使用的明文:

代码语言:javascript
复制
echo -n 'oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=' | base64 -d | openssl aes-128-ecb -d -K F3229A0B371ED2D9441B830D21A390C3

同样,注意确保所有输入都被正确地传递进来。上述命令产生:

代码语言:javascript
复制
bill.smith@gmail.com

太棒了。我们能够在MySQL中加密一些明文,然后在openssl中进行反向加密,并且它起了作用。现在,让我们看看是否可以在PHP中欺骗密文。让我们试试这个:

代码语言:javascript
复制
$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端使用其他模式进行加密(有关这方面的更多信息,请参见https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html )。

票数 3
EN

Stack Overflow用户

发布于 2021-06-08 12:11:27

我们在Mcrypt_encrypt & mcrypt_decrypt中找到了解决方案

MySql:

选择TO_BASE64(AES_ENCRYPT('selvamani',‘34/xrbFET445QS0’)为enc

选择AES_DECRYPT(FROM_BASE64("Bdc3RbB4rU3vBrkdIjTFoQ=="),'34/xrbFET445QS0')作为AES_DECRYPT(FROM_BASE64(“Bdc3RbB4rU3vBrkdIjTFoQ==”),

PHP:

$val = "selvamani";$key = "34/xrbFET445QS0";$pad_value = 16-(strlen( $val ) % 16);$val= str_pad($val,16*(楼层($val)/16)+1),chr($pad_value);$data = $key,$val,MCRYPT_MODE_ECB,mcrypt_create_iv( mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,mcrypt_create_iv),mcrypt_create_iv);回声base64_encode($data);

$key = "34/xrbFET445QS0";$val = base64_decode("Bdc3RbB4rU3vBrkdIjTFoQ==");$val = $val $key、$val、MCRYPT_MODE_ECB、mcrypt_create_iv( mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_ECB)、MCRYPT_DEV_URANDOM);

回声$val;

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67732941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档