我正在创建一个系统,用户可以通过PHP使用MySQL数据库存储消息,我使用MySQL AES_ENCRYPT函数来加密这些消息的内容。
这是我的帖子表:
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;
我的用户表:
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-hashed连接,以及中间的发布用户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`
然后突然间,它起作用了:
我真的不知道是什么原因引起的。有没有人有任何想法?
答案 0 :(得分:9)
更新 CAST
到CHAR
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
示例输出:
| ID | USER | ... | REALBODY | ---...------------------------ | 2 | 2 | ... | Post 2 | | 1 | 1 | ... | Post 1 |
这是 SQLFiddle 演示