Oracle和MySQL中的AES加密给出了不同的结果

Dan*_*Dan 7 mysql oracle encryption plsql

我需要比较Oracle数据库和MySQL数据库之间的数据.

在Oracle中,数据首先使用AES-128算法加密,然后进行散列.这意味着无法恢复数据并对其进行解密.

MySQL和纯文本中提供了相同的数据.因此,为了比较数据,我尝试加密然后散列MySQL数据,同时遵循Oracle中完成的相同步骤.

经过多次尝试,我终于发现aes_encryptMySQL中的结果与Oracle中的结果不同.

-- ORACLE:
-- First the key is hashed with md5 to make it a 128bit key:
raw_key := DBMS_CRYPTO.Hash (UTL_I18N.STRING_TO_RAW ('test_key', 'AL32UTF8'), DBMS_CRYPTO.HASH_MD5);

-- Initialize the encrypted result
encryption_type:= DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;

-- Then the data is being encrypted with AES:
encrypted_result := DBMS_CRYPTO.ENCRYPT(UTL_I18N.STRING_TO_RAW('test-data', 'AL32UTF8'), encryption_type, raw_key);
Run Code Online (Sandbox Code Playgroud)

oracle代码的结果将是: 8FCA326C25C8908446D28884394F2E22

-- MySQL
-- While doing the same with MySQL, I have tried the following:
SELECT hex(aes_encrypt('test-data', MD5('test_key'));
Run Code Online (Sandbox Code Playgroud)

MySQL代码的结果将是: DC7ACAC07F04BBE0ECEC6B6934CF79FE

我错过了什么吗?或者不同语言之间的加密方法不一样?

更新: 根据下面的评论,我相信我应该提到DBMS_CRYPTO.HashOracle中的结果MD5与MySQL中函数返回的结果相同的事实.

同样使用CBCCBE在Oracle中给出相同的结果,因为IV没有传递给函数,因此使用的是IV的默认值.NULL

BOUNTY: 如果有人可以验证我的最后评论,并且如果双方使用相同的填充,将产生相同的结果获得赏金:

@rossum MySQL中的默认填充是PKCS7,mmm ......哦..在Oracle中它使用PKCS5,简直不敢相信我没注意到.谢谢.(顺便说一下Oracle没有PAD_PKCS7选项,至少不是11g)

Cod*_*odo 8

MySQL的MD5函数返回一个32个十六进制字符的字符串.它被标记为二进制字符串,但它不是人们期望的16字节二进制数据.

所以要修复它,必须将此字符串转换回二进制数据:

SELECT hex(aes_encrypt('test-data', unhex(MD5('test_key'))));
Run Code Online (Sandbox Code Playgroud)

结果是:

8FCA326C25C8908446D28884394F2E22
Run Code Online (Sandbox Code Playgroud)

它又是一个由32个十六进制字符组成的字符串.但是否则它与Oracle的结果相同.

而BTW:

  • MySQL使用PKCS7填充.
  • PKCS5填充和PKCS7填充是同一个.所以Oracle填充选项是正确的.
  • MySQL使用ECB分组密码模式.因此,您必须相应地调整代码.(它对前16个字节没有任何影响.)
  • MySQL不使用初始化向量(与Oracle代码相同).
  • MySQL使用非标准折叠键.因此,要在MySQL和Oracle(或.NET或Java)中实现相同的结果,只使用16字节长的密钥.