我使用以下代码将用户密码存储到mysql表中,密码列是BINARY(20)
类型:
$salted_hash = sha1($salt . $password);
$sql = sprintf("INSERT INTO foo(user, password) VALUES ('guest', UNHEX('%s'))", $salted_hash);
匹配密码的选择查询如下:
$salted_hash = sha1($salt . $password);
$sql = sprintf("SELECT `userID` FROM `foo` WHERE `user`='guest' AND `password`=UNHEX('%s')", $salted_hash);
当我连接到运行在windows或mac机器上的web服务器时,代码工作正常。然而,我的生产网络主机是一台linux机器,SELECT
在那里失败了。
我只能phpMyAdmin
到我的web主机(mhpMyAdmin版本3.4.7.1)。通过phpMyAdmin,我执行以下查询:
SELECT UNHEX('3530280EDB5AA715929266D1D6F0423ABC27B104')
显示的结果是相同的十六进制数字3530280EDB5AA715929266D1D6F0423ABC27B104
,这似乎表明UNHEX
函数在linux上没有做任何事情。
如果我在Mac上的Sequel Pro执行相同的查询,我会得到50(ÛZ§fÑÖðB:¼'±
。
我不知道发生了什么事,也不知道该去哪里看。我认为要么phpMyAdmin不能显示二进制或确实有一些问题与UNHEX(似乎不一样)任何帮助是感激的。
这似乎是一个可配置的设置:"显示二进制内容为HEX"。我已经在同一服务器上尝试了您的查询…
SELECT UNHEX('3530280EDB5AA715929266D1D6F0423ABC27B104')
…但是使用两个不同的客户端。我可以确认phpMyAdmin以您发现的方式转义二进制输出。您可以使用以下命令再次检查输出是否正确:
SELECT HEX(UNHEX('3530280EDB5AA715929266D1D6F0423ABC27B104'))='3530280EDB5AA715929266D1D6F0423ABC27B104'
…,它应该返回1,或者使用简单的PHP脚本运行原始查询。总而言之:UNHEX()
没有任何问题。
我使用过的大多数托管服务实际上都允许外部MySQL客户端,你只需要在控制面板中启用它。确保不是这样的。如果你可以连接Sequel Pro,那么使用一个愚蠢的web客户端是愚蠢的。
我建议你进一步调试你的PHP代码。我不清楚如何构建哈希来匹配(是否在其他查询中检索盐?)。
如果你正在阅读这篇文章,是因为上面的解决方案都不适合你(和我一样)。
我已经解决了使用存储过程…
CREATE DEFINER=`root`@`%` PROCEDURE `SearchMessage`(IN code_to_search VARCHAR(255))
BEGIN
SELECT * FROM tablename WHERE UPPER(UNHEX(SUBSTRING(hex_field,25))) like CONCAT('%',UPPER(TRIM(text_to_search)),'%') COLLATE latin1_swedish_ci;
END
希望能有所帮助。