Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL的问题';s AES_解密_Php_Mysql_Security_Encryption_Aes - Fatal编程技术网

Php MySQL的问题';s AES_解密

Php MySQL的问题';s AES_解密,php,mysql,security,encryption,aes,Php,Mysql,Security,Encryption,Aes,我正在寻找一种方法,在数据进入MySQL数据库的过程中对其进行加密,然后在输出的过程中对其进行解密。此外,我希望能够在这些字段上执行正常的SQL查询,例如搜索和比较,这会阻止我使用纯PHP解决方案 这就引出了AES_ENCRYPT()和AES_DECRYPT(),它们可以在PHP中使用MCRYPT进行复制 我在使用AES_DECRYPT时遇到了困难,我尝试了通过在线搜索找到的所有建议 这是我的桌子: CREATE TABLE IF NOT EXISTS `test_table` ( `id`

我正在寻找一种方法,在数据进入MySQL数据库的过程中对其进行加密,然后在输出的过程中对其进行解密。此外,我希望能够在这些字段上执行正常的SQL查询,例如搜索和比较,这会阻止我使用纯PHP解决方案

这就引出了AES_ENCRYPT()和AES_DECRYPT(),它们可以在PHP中使用MCRYPT进行复制

我在使用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


有什么想法,或者更好的解决方案吗?

AES\u ENCRYPT返回一个二进制字符串,因此不要使用文本列类型

提示:在
1
处开始主键编号,而不是
0

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


AES\u ENCRYPT返回一个二进制字符串,因此不要使用文本列类型

提示:在
1
处开始主键编号,而不是
0

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


Blob解密工作正常,“54657374696e67”是“测试”,只有十六进制编码。您可能正在使用一个将blob显示为十六进制的工具执行此操作。文本解密不起作用(也应该不起作用)。

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

MySQL中的文本字段需要进行字符集转换。如果您使用iso-8859连接,并且该表存储在CP1252中,那么MySQL将在两个字符集之间自动转换文本。这将丢弃加密的数据,因为原始8859数据的某些字节将转换为1252的等效字节,这些字节具有不同的值


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

MySQL中的文本字段需要进行字符集转换。如果您使用iso-8859连接,并且该表存储在CP1252中,那么MySQL将在两个字符集之间自动转换文本。这将丢弃加密的数据,因为原始8859数据的某些字节将转换为1252的等效字节,这些字节具有不同的值


另一方面,BLOB字段是逐字传递的,没有转换,因此解密时不会出错。

如果使用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

如果使用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

同意@user187291

我遇到了同样的问题,并在我的phpmyadmin中发现了一个选中的选项

将二进制内容显示为十六进制


当我在mysql命令行中运行相同的查询时,它向我显示了正确的结果

同意@user187291

我遇到了同样的问题,并在我的phpmyadmin中发现了一个选中的选项

将二进制内容显示为十六进制


当我在mysql命令行中运行相同的查询时,它向我显示了正确的结果

一个cast会将解密的文本直接转换为原始格式:

SELECT *, CAST(AES_DECRYPT(encrypted_blob,'key') AS text) FROM test_table WHERE id = 1;

强制转换会将解密文本直接转换为原始格式:

SELECT *, CAST(AES_DECRYPT(encrypted_blob,'key') AS text) FROM test_table WHERE id = 1;

AES_ENCRYPT不只是返回值吗?我有两个字段“encrypted”和“encrypted_blob”用于测试,因为我知道需要一个二进制字段。我已经用你的提示更新了我的代码,结果是一样的。非常有趣的提示;我一定会进一步调查的。谢谢
AES_ENCRYPT
返回二进制,因此不要将其结果存储在文本列中。您的第一次更新是将其存储在文本列中。这可能会导致加密/解密错误。谢谢-我在文本栏的目标是查看发生了什么。我现在明白了二进制列是必要的,而文本列是完全无用的。AES_ENCRYPT不是只返回值吗?我有两个字段“encrypted”和“encrypted_blob”用于测试,因为我知道需要一个二进制字段。我已经用你的提示更新了我的代码,结果是一样的。非常有趣的提示;我一定会进一步调查的。谢谢
AES_ENCRYPT
返回二进制,因此不要将其结果存储在文本列中。您的第一次更新是将其存储在文本列中。这可能会导致加密/解密错误。谢谢-我在文本栏的目标是查看发生了什么。我现在明白了二进制列是必要的,而文本列是完全无用的。根据定义,所有加密都是可逆的。您将消息摘要函数与密码混淆。translation md5()不是加密,它是一个散列函数。如果您只想存储加密的值,您应该在PHP中对它们进行加密,并将它们作为blob写入。这样,密钥永远不会离开PHP,因此数据库对攻击者没有用处。您在这里所做的似乎是在数据库中进行加密和解密,这提供的保护要少得多。毕竟,您现在必须在每次查询时通过网络发送(纯文本!)键。最后,Rook有一点,如果您存储的是密码,那么您应该使用摘要,而不是加密。根据定义,所有加密都是可逆的。您将消息摘要函数与密码混淆。translation md5()不是加密,它是一个哈希函数。如果您只想存储加密的值,您应该在PH中对它们进行加密