在INSERT和UPDATE上,mysql加密的行为是否有所不同?

时间:2012-05-16 17:20:12

标签: python mysql encryption

我正在编写一个快速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参数(作为字符串)。有没有理由为什么数据层会进行不同的加密,或者我是在咆哮错误的树?

2 个答案:

答案 0 :(得分:1)

首先:如果您能提供帮助,请不要使用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)

答案 1 :(得分:1)

如果你使用不带盐的加密,它将使用基于当前时间的盐,所以每次你调用它,你会得到一个不同的哈希:

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/ |
+------------------------------------------------------------------------------------------------------------+

所以这一切都取决于你使用的盐。永远不要使用无盐的哈希。