【问题标题】:BLOB data returned in MySQL using AES_DECRYPT with ORDER clause使用带有 ORDER 子句的 AES_DECRYPT 在 MySQL 中返回的 BLOB 数据
【发布时间】:2013-08-06 05:27:39
【问题描述】:

我正在创建一个系统,用户可以在其中通过 PHP 和 MySQL 数据库存储消息,并且我正在使用 MySQL AES_ENCRYPT 函数来加密这些消息的内容。

这是我的 posts 表:

CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` int(11) DEFAULT NULL,
  `group` int(11) DEFAULT NULL,
  `body` varbinary(1000) NOT NULL,
  `ip` varchar(45) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `replyto` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `replyto` (`replyto`),
  KEY `user` (`user`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;


ALTER TABLE `posts`
  ADD CONSTRAINT `posts_ibfk_3` FOREIGN KEY (`replyto`) REFERENCES `posts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  ADD CONSTRAINT `posts_ibfk_4` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;

还有我的 users 表:

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(45) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `email` varchar(100) NOT NULL,
  `name` varchar(100) NOT NULL,
  `hash` varchar(128) NOT NULL,
  `salt` varchar(32) NOT NULL,
  `guid` varchar(36) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

我用于消息正文的 AES 加密密钥是前缀和后缀字符串之间的 SHA-512 哈希连接,中间是发布用户的 GUID。因此,我有以下 SQL 查询来选择最近的消息:

SELECT AES_DECRYPT(`posts`.`body`, SHA2(CONCAT('prefix',(`users`.`guid`),'suffix'),512)) AS 'realbody'
FROM `posts`
INNER JOIN `users` ON `posts`.`user` = `users`.`id` 
ORDER BY `posts`.`id` DESC

不幸的是,这不会返回解密的消息,如您在屏幕截图中所见:

相反,我正在获取此 BLOB 数据。但是,如果我从查询中删除 ORDER BY 子句:

SELECT AES_DECRYPT(`posts`.`body`, SHA2(CONCAT('prefix',(`users`.`guid`),'suffix'),512)) AS 'realbody'
FROM `posts`
INNER JOIN `users` ON `posts`.`user` = `users`.`id` 

然后突然,它起作用了:

我真的不知道是什么原因造成的。有人有什么想法吗?

【问题讨论】:

    标签: mysql database sql-order-by blob aes


    【解决方案1】:

    已更新 CASTCHAR

    SELECT `posts`.*, CAST(AES_DECRYPT(`posts`.`body`,SHA2(CONCAT('prefix',`users`.`guid`,'suffix'),512)) AS CHAR) as 'realbody'
      FROM `posts` JOIN `users` 
        ON `posts`.`user` = `users`.`id`
     ORDER BY `posts`.`id` DESC
    

    样本输出:

    |身份证 |用户 | ... |真人 | ------------------- | 2 | 2 | ... |发表 2 | | 1 | 1 | ... |发表 1 |

    这里是SQLFiddle演示

    【讨论】:

    • 好主意,但不幸的是我仍然有同样的问题。
    • @WilliamThomas 你能用几行样本数据创建一个 sqlfiddle 吗?
    • 我刚刚做了,但不幸的是它看起来无论如何都返回了二进制数据:sqlfiddle.com/#!2/4ccd9a/4/0
    • 哦,哇,我应该尝试一下。工作得很好,谢谢!
    猜你喜欢
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    相关资源
    最近更新 更多