玩哈希密码返回错误结果



我正在使用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==

怎么样?如何修复?或者我必须实现自己的解决方案?

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

MD5输出一个16个字节的序列,每个字节(可能)具有0到255(包括0和255)之间的任何值。当您想打印值时,需要将字节转换为"可打印字符"序列。有几种可能的约定,两种主要的是十六进制Base64

在十六进制表示法中,每个字节值都表示为两个"十六进制数字":这样的数字要么是十进制数字(从"0"到"9"),要么是字母(从"a"到"f",大小写无关)。因此,16个字节变为32个字符。

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

这里,'8WgrVN5X0gK6lHoK8mOZ/Q=='是一个16字节序列的Base64编码,第一个字节的值为241,第二个字节为104,然后为43,依此类推。在十六进制记数法中,第一字节用'f1'表示,第二字节用'68',第三字节用'2b'表示。。。16个字节的完整序列的十六进制表示法是"f1682b54de57d202ba947a0af2639fd",这是您所期望的值。

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

正如Nickolay所说,您正在比较十六进制字符串与Base-64字符串。此外,我建议使用BCrypt,而不是Play的加密工具。

相关内容

  • 没有找到相关文章

最新更新