2010-09-15 80 views
1

我正在寻找一种将数据加密到MySQL数据库的方法,并在出口时将其解密。此外,我希望能够对这些字段执行正常的SQL查询,例如搜索和比较,这使我无法使用纯PHP解决方案。MySQL的AES_DECRYPT问题

这导致我使用AES_ENCRYPT()和AES_DECRYPT(),它可以使用MCRYPT在PHP中复制。

我很难与AES_DECRYPT并尝试所有建议,我可以通过在线搜索找到。

这里是我的表:

CREATE TABLE IF NOT EXISTS `test_table` (
    `id` int(6) NOT NULL, 
    `secure_info` text NOT NULL, 
    `encrypted_blob` blob NOT NULL, 
    `encrypted` text NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

我执行这些查询:

INSERT INTO test_table (id, secure_info) VALUES (1,'Testing'); 
UPDATE test_table SET encrypted = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 
UPDATE test_table SET encrypted_blob = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 

SELECT *, AES_DECRYPT(encrypted,'key') as decrypted, AES_DECRYPT(encrypted_blob,'key') as decrypted_blob FROM test_table WHERE id=1; 

我无法得到原始值。 'decrypted'返回NULL,'decrypted_blob'返回54657374696e67

任何想法,或者更好的解决方案?

+0

所有加密是通过定义可逆的。您使用密码混淆了消息摘要功能。翻译md5()不加密其散列函数。 – rook 2010-09-16 01:51:42

+0

如果你只是想存储加密值,你应该用PHP加密它们并将它们写成斑点。这样,密钥永远不会离开PHP,因此数据库对攻击者无用。你似乎在做的是在数据库中进行加密和解密,这提供了更少的保护。毕竟,您现在必须通过每条查询在电线上发送(纯文本!)键。最后,Rook有一点,因为如果你存储密码而不是加密,你应该使用摘要。 – 2010-09-18 02:09:26

回答

4

斑点解密工作得很好, “54657374696e67” 是 “测试”,只有十六进制编码。你可能用一个将blob显示为十六进制的工具来执行此操作。文本解密不起作用(也不应该)。

+0

谢谢 - 这是我遇到的最大麻烦。我的数据库也设置在UNHEX()的出路上 - 当我选择时,我会得到原始文本! – Travis 2010-09-17 22:22:07

+1

好的。你甚至没有看到十六进制码。所有你看到的是金发,黑发,红发,测试... – webbiedave 2010-09-20 15:03:52

0

AES_ENCRYPT返回一个二进制字符串,所以不要使用文本列类型。

提示:在1启动主键编号,而不是0

提示2:尽量不要命名MySQL的关键字后,您的领域。这可能会导致混淆,通常需要使用反引号进行转义(text是个例外)。

http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html

+0

不是AES_ENCRYPT只是返回值?我有两个字段,'加密'和'encrypted_blob'进行测试,因为我知道需要一个二进制字段。我已经用你的提示更新了我的代码,结果也是一样。非常有趣的提示;我一定会进一步研究它们。谢谢! – Travis 2010-09-15 19:00:27

+0

'AES_ENCRYPT'返回二进制数,因此不要将结果存储在文本列中。你的第一个'UPDATE'将它存储在一个文本列中。这可能导致加密/解密错误。 – webbiedave 2010-09-15 20:45:34

+0

谢谢 - 我的文字栏的目标是看看发生了什么。我现在明白,二进制列是必要的,而文本列完全没用。 – Travis 2010-09-17 22:19:51

2

MySQL中的TEXT字段受制于字符集转换。如果您使用iso-8859连接并且表格存储在CP1252中,那么MySQL会自动转换两个字符集之间的文本。这会破坏加密的数据,因为原始8859数据的一些字节将被转换为1252的等值,这些等值具有不同的值。

另一方面,BLOB字段是逐字传递的,没有转换,所以没有错误解密。

+0

谢谢 - 这是非常有益的! – Travis 2010-09-17 22:24:11

0

如果您使用AES_ENCRYPT加密字符串,则AES_DECRYPT不会返回字符串,而是返回System.Byte的数组。我使用下面的代码将其还原为一个字符串:

  Dim back As System.Byte() 
      back = DirectCast(reader(x), System.Byte()) 
      Dim s As String = "" 
      For Each b As Byte In back 
       s &= Chr(b) 
      Next 
0

同意@ user187291

我有同样的问题,并发现了我的phpmyadmin检查选项

显示二进制内容HEX

当我运行在MySQL命令行相同的查询它显示我正确的结果