简体   繁体   中英

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. Mqsql encryption working fine, I am used the below method for 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. In php we are used below like this

 $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. 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). 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. 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.

  • 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. 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 ). So, to encrypt the plaintext 'bill.smith@gmail.com' with the key F3229A0B371ED2D9441B830D21A390C3 using aes_128_ecb mode in MySQL, we could do this:

 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. 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. The above statement produces the following base64-encoded ciphertext:

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:

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. Now, let's see if we can decypt the ciphertext in 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. What could be wrong?

Running openssl_get_cipher_methods , on my system, I see that aes-128-ecb is not supported. That's not surprising, because aes-128-ecb has known weaknesses . 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

MySql:

SELECT TO_BASE64(AES_ENCRYPT('selvamani', '34/xrbFET445QS0')) AS enc

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

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_RIJNDAEL_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_ECB), MCRYPT_DEV_URANDOM)) ;

echo $val;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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