简体   繁体   English

MySql AES_DECRYPT & AES_ENCRYPT 密钥在 PHP 中不起作用

[英]MySql AES_DECRYPT & AES_ENCRYPT Key is not working in PHP

In Our project we planned to store the data as encrypted format in mysql database, We used php & MqSql in Our Project.在我们的项目中,我们计划将数据以加密格式存储在 mysql 数据库中,我们在我们的项目中使用了 php 和 MqSql。 Mqsql encryption working fine, I am used the below method for 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 

But We are not able to decrypt the string in PHP witch is encrypted by MqSql.但是我们无法解密 PHP 中的字符串,它是由 MqSql 加密的。 In php we are used below like this在 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);     

When working with AES to encrypt using one library, then decrypt using a different library, it's important to make sure that all of the subtleties are the same on both sides.当使用 AES 使用一个库进行加密,然后使用不同的库进行解密时,重要的是要确保双方的所有细节都相同。 For example.例如。

  • AES has many modes (eg aes-128-cbc, aes_128-ecb, aes-128-gcm, aes-256-cbc, aes_256-ecb, aes-256-gcm, and many more). AES 有许多模式(例如 aes-128-cbc、aes_128-ecb、aes-128-gcm、aes-256-cbc、aes_256-ecb、aes-256-gcm 等等)。 It's important to use the same mode for both encryption and decryption.对加密和解密使用相同的模式很重要。

  • Many AES encryption/decryption functions allow you to pass-in a password, instead of a key, and internally the function derives a key from the password.许多 AES 加密/解密函数允许您传入密码而不是密钥,并且 function 在内部从密码派生密钥。 However, this is usually fraught with problems when going from one library to another, because the methods used internally for key derivation vary widely between different implementations.然而,当从一个库转移到另一个库时,这通常充满了问题,因为内部用于密钥派生的方法在不同的实现之间差异很大。 So, it's best to pass a key directly (of the correct length, for the AES mode that you are using), instead of passing a password.因此,最好直接传递密钥(长度正确,适用于您使用的 AES 模式),而不是传递密码。

  • Encryption and decryption functions often expect inputs such as plaintext, ciphertext, key's, iv's, etc. to be passed-in as raw bytes, not text.加密和解密函数通常期望明文、密文、密钥、iv 等输入作为原始字节而不是文本传入。 Pay attention to this, and make sure that you pass-in raw bytes when required.请注意这一点,并确保在需要时传入原始字节。 Likewise, encryption and decryption functions often produce outputs in raw bytes.同样,加密和解密函数通常会产生原始字节的输出。 Be sure to handle these accordingly.一定要相应地处理这些。

MySQL uses aes_128_ecb mode by default (see https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html ). MySQL uses aes_128_ecb mode by default (see https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html ). So, to encrypt the plaintext 'bill.smith@gmail.com' with the key F3229A0B371ED2D9441B830D21A390C3 using aes_128_ecb mode in MySQL, we could do this:因此,要在 MySQL 中使用 aes_128_ecb 模式使用密钥 F3229A0B371ED2D9441B830D21A390C3 加密明文“bill.smith@gmail.com”,我们可以这样做:

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

Note that the key is provided as a hex-encoded string of the correct length for the mode that is being used (128 bytes), and we are using UNHEX() to convert it to raw bytes as required by the MySQL aes_encrypt() function.请注意,密钥是作为正在使用的模式(128 字节)的正确长度的十六进制编码字符串提供的,我们使用 UNHEX() 将其转换为 MySQL aes_encrypt() function 要求的原始字节. The aes_encrypt() fucntion produces raw bytes as its output, and we are using to_base64() to base64-encode these raw bytes to produce displayable text. aes_encrypt() 函数生成原始字节作为其 output,我们使用 to_base64() 对这些原始字节进行 base64 编码以生成可显示的文本。 The above statement produces the following base64-encoded ciphertext:上面的语句产生以下 base64 编码的密文:

oPN1EIfxX+MFMfcp2jTjjB55QVUURKV8lbfcwhT3MMk=

Let's see if we can decrypt this using the same key, with openssl on the command line, and see if produces the plaintext that we started with:让我们看看我们是否可以使用相同的密钥解密它,在命令行上使用 openssl,看看是否会生成我们开始使用的明文:

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

Again, note care taken to make sure all of the inputs are passed in correctly.同样,请注意确保所有输入都正确传递。 The above command produces:上面的命令产生:

bill.smith@gmail.com

Great.伟大的。 We were able to encrypt some plaintext in MySQL, then do the reverse in openssl, and it worked.我们能够在 MySQL 中加密一些明文,然后在 openssl 中执行相反的操作,并且成功了。 Now, let's see if we can decypt the ciphertext in PHP.现在,让我们看看我们是否可以解密 PHP 中的密文。 Let's try this:让我们试试这个:

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

Again, note the care taken to pass everything in correctly.同样,请注意正确传递所有内容的注意事项。 But, on my system, the above code snippet produces no output.但是,在我的系统上,上面的代码片段没有产生 output。 What could be wrong?有什么问题?

Running openssl_get_cipher_methods , on my system, I see that aes-128-ecb is not supported.在我的系统上运行openssl_get_cipher_methods ,我看到不支持 aes-128-ecb。 That's not surprising, because aes-128-ecb has known weaknesses .这并不奇怪,因为 aes-128-ecb 有已知的弱点 To solve the problem, it would be best to encrypt using some other mode on the MySQL side (see https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html for more info on this). To solve the problem, it would be best to encrypt using some other mode on the MySQL side (see https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html for more info on this) .

We got the Solution in Mcrypt_encrypt & mcrypt_decrypt我们在 Mcrypt_encrypt 和 mcrypt_decrypt 中得到了解决方案

MySql: MySql:

SELECT TO_BASE64(AES_ENCRYPT('selvamani', '34/xrbFET445QS0')) AS enc SELECT TO_BASE64(AES_ENCRYPT('selvamani', '34/xrbFET445QS0')) 作为编码

SELECT AES_DECRYPT(FROM_BASE64("Bdc3RbB4rU3vBrkdIjTFoQ=="),'34/xrbFET445QS0') AS decrypt_string SELECT AES_DECRYPT(FROM_BASE64("Bdc3RbB4rU3vBrkdIjTFoQ=="),'34/xrbFET445QS0') AS decrypt_string

PHP: PHP:

$val = "selvamani"; $val = "塞尔瓦玛尼"; $key = "34/xrbFET445QS0"; $key = "34/xrbFET445QS0"; $pad_value = 16-(strlen($val) % 16); $pad_value = 16-(strlen($val) % 16); $val = str_pad($val, (16*(floor(strlen($val) / 16)+1)), chr($pad_value)); $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_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_DEV_URANDOM)) ; $data = Mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $val, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_DEV_URANDOM)) ; echo base64_encode($data);回声 base64_encode($data);

$key = "34/xrbFET445QS0"; $key = "34/xrbFET445QS0"; $val = base64_decode("Bdc3RbB4rU3vBrkdIjTFoQ=="); $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_ECB), MCRYPT_DEV_URANDOM)) ; $val = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $val, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_DEV_URANDOM)) ;

echo $val;回声 $val;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM