玩!哈希密码返回错误结果

时间:2011-06-08 13:21:09

标签: hash passwords md5 playframework

我正在使用Play 1.2.1。我想哈希我的用户密码。我认为Crypto.passwordHash会很好,但事实并非如此。 passwordHash文档说它返回MD5密码哈希。我在fixture中创建了一些用户帐户,我把md5密码哈希:

  ...
User(admin):
  login: admin
  password: f1682b54de57d202ba947a0af26399fd
  fullName: Administrator
  ...

问题是,当我尝试使用以下内容登录时:

user.password.equals(Crypto.passwordHash(password))

它不起作用。所以我在我的autentify方法中添加了一个日志语句:

Logger.info("\nUser hashed password is %s " +
                    "\nPassed password is %s " +
                    "\nHashed passed password is %s",
                    user.password, password, Crypto.passwordHash(password));

密码哈希确实不同,但是嘿! passwordHash方法的输出甚至不是MD5哈希:

15:02:16,164 INFO  ~
User hashed password is f1682b54de57d202ba947a0af26399fd
Passed password is <you don't have to know this :P>
Hashed passed password is 8WgrVN5X0gK6lHoK8mOZ/Q==

怎么样?怎么解决?或许我必须实施自己的解决方案?

3 个答案:

答案 0 :(得分:5)

Crypto.passwordHash返回base64编码的密码哈希,而您正在与十六进制编码进行比较。

答案 1 :(得分:3)

MD5输出16个字节的序列,每个字节具有(可能)0到255(含)之间的任何值。如果要打印该值,则需要将字节转换为“可打印字符”序列。有几种可能的约定,两个主要是十六进制 Base64

以十六进制表示法,每个字节值表示为两个“十六进制数字”:这样的数字是十进制数字('0'到'9')或字母(从'a'到'f',用例是无关紧要的)。因此16个字节变为32个字符。

在Base64编码中,每组三个连续字节被编码为四个字符,采用64个可能字符(数字,小写字母,大写字母,'+'和'/')的列表。可以添加一个或两个最后的'='符号,以便编码的字符串包含多个4的字符。

这里,'8WgrVN5X0gK6lHoK8mOZ / Q =='是16字节序列的Base64编码,第一个具有值241,第二个具有值104,然后是43,依此类推。在十六进制表示法中,第一个字节由'f1'表示,第二个字节由'''表示,第三个字节由'2b'表示...而16字节的完整序列的十六进制表示法则为'f1682b54de57d202ba947a0af26399fd',值为你期望的那样。

play.libs.Codec类包含用于解码和编码Base64和十六进制表示法的方法。它还包含Codec.hexMD5(),它执行MD5哈希并以十六进制表示法返回值,而不是Base64。

答案 2 :(得分:2)

正如Nickolay所说,你正在比较Hex和Base-64字符串。另外,我建议使用BCrypt,而不是Play的加密工具。