我正在使用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==
怎么样?怎么解决?或许我必须实施自己的解决方案?
答案 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的加密工具。