我正在将基于joomla的cms系统的一些数据迁移到基于Spring的Java EE环境。
在分析过程中我发现密码的md5实现与joomla不一样???任何想法为什么md5实现差异?
例如:
如果joomla记录有一个密码字段,如“3c57ebfec712312f30c3fd1981979f58:WnvTroeiBmd5bjGmmsVUnNjppadH7giK
”(这里3c57ebfec712312f30c3fd1981979f58
是最终的md5哈希摘要,WnvTroeiBmd5bjGmmsVUnNjppadH7giK
是附加用户密码输入的关键字),当用户尝试登录时在弹簧系统中这个记录失败了。
在基于Spring的Java EE系统中,我们使用哈希编码器作为md5,将盐用作某个变量,WnvTroeiBmd5bjGmmsVUnNjppadH7giK
在这里。
Junit Code代码段:此测试用例失败。
@Test
public void testSpringMD5Functionality() {
String md5MigratedPassword = "3c57ebfec712312f30c3fd1981979f58:WnvTroeiBmd5bjGmmsVUnNjppadH7giK";
String[] m = md5MigratedPassword.split(":");
Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder();
passwordEncoder.setEncodeHashAsBase64(false);
boolean value = passwordEncoder.isPasswordValid(m[0], "password", m[1]);
assertTrue(value); //test case fails ?????
}
答案 0 :(得分:2)
以上不起作用(包括挑战评论)。以下代码来自此处 - http://forum.joomla.org/viewtopic.php?t=207689#p993378并确认适用于盐渍和非盐渍密码。
public class Joomla15PasswordHash
{
public static boolean check(String passwd,String dbEntry) {
if (passwd==null || dbEntry==null || dbEntry.length()==0)
throw new IllegalArgumentException();
String[] arr = dbEntry.split(":",2);
if (arr.length==2) {
// new format as {HASH}:{SALT}
String cryptpass = arr[0];
String salt = arr[1];
return md5(passwd+salt).equals(cryptpass);
} else {
// old format as {HASH} just like PHPbb and many other apps
String cryptpass = dbEntry;
return md5(passwd).equals(cryptpass);
}
}
static Random _rnd;
public static String create(String passwd) {
StringBuffer saltBuf = new StringBuffer();
synchronized (Joomla15PasswordHash.class) {
if (_rnd==null) _rnd=new SecureRandom();
int i;
for (i=0;i<32;i++) {
saltBuf.append(Integer.toString(_rnd.nextInt(36),36));
}
}
String salt = saltBuf.toString();
return md5(passwd+salt)+":"+salt;
}
/** Takes the MD5 hash of a sequence of ASCII or LATIN1 characters,
* and returns it as a 32-character lowercase hex string.
*
* Equivalent to MySQL's MD5() function
* and to perl's Digest::MD5::md5_hex(),
* and to PHP's md5().
*
* Does no error-checking of the input, but only uses the low 8 bits
* from each input character.
*/
private static String md5(String data) {
byte[] bdata = new byte[data.length()]; int i; byte[] hash;
for (i=0;i<data.length();i++) bdata[i]=(byte)(data.charAt(i)&0xff );
try {
MessageDigest md5er = MessageDigest.getInstance("MD5");
hash = md5er.digest(bdata);
} catch (GeneralSecurityException e) { throw new RuntimeException(e); }
StringBuffer r = new StringBuffer(32);
for (i=0;i<hash.length;i++) {
String x = Integer.toHexString(hash[i]&0xff);
if (x.length()<2) r.append("0");
r.append(x);
}
return r.toString();
}
}
答案 1 :(得分:0)
Spring的Md5PasswordEncoder从未声称与Joomla的盐渍MD5密码兼容。
简而言之,它无法运作。你需要Java代码做与Joomla相同的事情。
http://forum.joomla.org/viewtopic.php?t=207689#p993378声称是这样一段代码,你应该尝试一下。
如果它不起作用,最可能的罪魁祸首可能是编码问题,你必须确保将Java字符串(16位宽字符)转换为PHP兼容的字节表示。
此外,您应该考虑迁移路径,以实现更强大的密码派生功能,例如PBKDF2。