![](/img/trans.png)
[英]Why does filtering a QuerySet behave differently for user vs. superuser?
[英]Does mysql encrypt behave differently on INSERT vs UPDATE?
我正在编写一个快速的REST服务来管理我们域的电子邮件帐户,并遇到了一个我无法解释的奇怪行为。
我使用mysql来验证电子邮件帐户,我们的REST服务使用Web界面管理maildirs并插入或更新auth凭证。 插入用户以及更新密码的查询都使用encrypt
mysql命令。
奇怪的是,在REST接口上更改密码至少一次之前,插入的用户将无法进行身份验证。 这意味着encrypt
正在为更新设置正确的值,但插入有问题。
我已经尝试在休息服务端的GET / POST参数中记录所有内容,看起来数据库层出现了问题。 REST服务在两个端口记录密码的params。 执行查询时的某些内容是不同的。
我的查询看起来像这样(在Python中使用MySQLdb):
ADD_USER = "INSERT INTO users (id,name,maildir,crypt) VALUES (%s,%s,%s,encrypt(%s));"
CHANGE_PASS = "UPDATE users SET crypt = encrypt(%s) WHERE id=%s"
同样, ADD_USER
正在输入一个错误的哈希值,其中CHANGE_PASS
成功,并且传递给它们的crypt
(作为字符串)具有完全相同的HTTP参数。 有没有理由为什么数据层会进行不同的加密,或者我咆哮错误的树?
首先:如果您可以提供帮助,请不要使用ENCRYPT()
作为密码。 它有点受限(例如:它忽略了密码的前8个字符以外的所有内容),并且它不是特别安全,特别是因为它意味着MySQL查询日志记录将记录用户的密码! 你可以更好地在Python中进行密码散列 - 这意味着不仅MySQL不必知道任何有关实际密码的信息,而且还允许你使用更强大的密码散列算法。
尽管如此,请记住, ENCRYPT()
不是纯哈希函数。 除非你传入salt作为第二个参数,否则它的结果不是常数。 你是如何检查密码的? 一个正确的解决方案看起来像:
SELECT * FROM users WHERE <...> AND crypt = ENCRYPT(%s, crypt) ...
或者,在Python中:
row.crypt == crypt.crypt(users_input_password, row.crypt)
如果你使用不带盐的加密,它将使用基于当前时间的盐,所以每次你调用它,你会得到一个不同的哈希:
mysql> select encrypt('test');
+-----------------+
| encrypt('test') |
+-----------------+
| 92SErC2PadiaQ |
+-----------------+
mysql> select encrypt('test');
+-----------------+
| encrypt('test') |
+-----------------+
| A2jgxXgOJx7ls |
+-----------------+
前两个字符(在标准情况下)是盐。 如果你想检查它,你使用旧密码作为salt,除了前两个字符之外的所有字符都被忽略:
mysql> select encrypt('test', 'A2jgxXgOJx7ls');
+----------------------------------+
| encrypt('test', 'A2jgxXgOJx7ls') |
+----------------------------------+
| A2jgxXgOJx7ls |
+----------------------------------+
如果你想要更强的密码,你必须使用特殊的盐:
mysql> select encrypt('test', '$1$12345678$') as md5;
+------------------------------------+
| md5 |
+------------------------------------+
| $1$12345678$oEitTZYQtRHfNGmsFvTBA/ |
+------------------------------------+
mysql> select encrypt('test', '$5$0123456789abcdef$') sha256;
+-----------------------------------------------------------------+
| sha256 |
+-----------------------------------------------------------------+
| $5$0123456789abcdef$Wm4jf6bGxEoelzY0H/fTvcw8Qcshq0hyLaRfZWtN8q. |
+-----------------------------------------------------------------+
mysql> select encrypt('test', '$6$0123456789abcdef$') as sha512;
+------------------------------------------------------------------------------------------------------------+
| sha512 |
+------------------------------------------------------------------------------------------------------------+
| $6$0123456789abcdef$vNATSYYTivQfXwPTUT4q.sRFLs/sgxDXaPipzRlX3WOO4r1NcR.Og5OoU2Cd2agm1WA3pCJ30JU4EKMxpZaDy/ |
+------------------------------------------------------------------------------------------------------------+
所以这一切都取决于你使用的盐。 永远不要使用无盐的哈希。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.