代码之家  ›  专栏  ›  技术社区  ›  Selvamani P

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

  •  0
  • Selvamani P  · 技术社区  · 4 年前

    在我们的项目中,我们计划将数据以加密格式存储在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);     
    
    0 回复  |  直到 4 年前
        1
  •  3
  •   mti2935    4 年前

    当使用AES使用一个库加密,然后使用另一个库解密时,重要的是要确保双方的所有微妙之处都是相同的。例如。

    • AES有许多模式(例如AES-128-cbc、AES_128-ecb、AES-128-gcm、AES-256-cbc、ae s_256-ecb、ae s-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-ebc不受支持。这并不奇怪,因为aes-128欧洲央行已经 known weaknesses 为了解决这个问题,最好在MySQL端使用其他模式进行加密(参见 https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html 了解更多信息)。

        2
  •  2
  •   Selvamani P    4 年前

    我们在Mcrypt_encrypt&mcrypt_decrypt

    MySql:

    选择TO_BASE64(AES_ENCRYPT(“selvamani”,“34/xrbFET445QS0”)作为加密

    选择AES_DECRYPT(FROM_BASE64(“Bdc3RbB4rU3vBrkdIjTFoQ==”)作为解密字符串

    PHP:

    $val=“塞尔瓦马尼”; $key=“34/xrbFET445QS0”; $pad_value=16-(字符串($val)%16); $val=str_pad($val,(16*(地板(strlen($val)/16)+1)),chr($pad_value)); $数据= Mcrypt_encrypt(Mcrypt_RIJNDAEL_128、$key、$val、Mcrypt_MODE_ECB、Mcrypt_create_iv(Mcrypt_get_iv_size(Mcrypt _RIJNDAL_128、Mcrypt _MODE_ECL)、MCRYPTA_DEV_URANDOM) ; echo base64_encode($data);

    $key=“34/xrbFET445QS0”; $val=base64_decode(“Bdc3RbB4rU3vBrkdIjTFoQ==”); $val= mcrypt_decrypt(mcrypt_RIJDAEL_128、$key、$val、mcrypt_MODE_ECB、mcrypt_create_iv(mcrypt_get_iv_size(mcrypt _RIJDEAL_128、mcrypt _MODE_ECL)、MCRYPTA_DEV_URANDOM) ;

    echo$val;