我正在寻找一种方法来加密进入MySQL数据库的数据,并在出路时对其进行解密。另外,我希望能够在这些字段上执行普通的SQL查询,例如搜索和比较,这使我无法使用纯PHP解决方案。
这导致我使用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 :(得分:4)
Blob解密工作正常,“54657374696e67”是“测试”,只有十六进制编码。您可能正在使用将blob显示为十六进制的工具执行此操作。文本解密不起作用(也不应该)。
答案 1 :(得分:2)
MySQL中的TEXT字段受字符集转换的影响。如果您正在连接iso-8859并且表格存储在CP1252中,那么MySQL将自动转换两个字符集之间的文本。这将废弃加密数据,因为原始8859数据的某些字节将转换为1252当量,具有不同的值。
另一方面,BLOB字段通过逐字传递而没有转换,所以没有错误解密。答案 2 :(得分:0)
AES_ENCRYPT返回二进制字符串,因此请勿使用文本列类型。
提示:在1
开始主键编号,而不是0
提示2:尽量不要在MySQL关键字后命名您的字段。这可能会导致混淆,并且通常需要使用反引号进行转义(text
是一个例外)。
答案 3 :(得分: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
答案 4 :(得分:0)
同意@ user187291
我遇到了同样的问题,并在我的phpmyadmin中找到了一个选项
将二进制内容显示为HEX
当我在mysql命令行中运行相同的查询时,它显示了正确的结果
答案 5 :(得分:0)
强制转换会将您解密的文本直接转换为原始格式:
SELECT *, CAST(AES_DECRYPT(encrypted_blob,'key') AS text) FROM test_table WHERE id = 1;