2012-02-09 3 views
1

joomla 기반 cms 시스템에서 스프링 기반 Java EE 환경으로 일부 데이터를 마이그레이션 중입니다.소금으로 인코딩 된 Md5

분석 중에 나는 암호의 md5 구현이 joomla와 같지 않다는 것을 알고 ??? 모든 아이디어 왜 md5 구현의 차이 ?? 예를 들어

: 줌라 레코드 "3c57ebfec712312f30c3fd1981979f58:WnvTroeiBmd5bjGmmsVUnNjppadH7giK"와 같은 암호 필드 있었다면 (여기 3c57ebfec712312f30c3fd1981979f58 최종 MD5 해시 다이제스트와 WnvTroeiBmd5bjGmmsVUnNjppadH7giK 사용자 비밀번호 입력에 추가되는 키이다) 사용자가이 기록에 로그인을 시도 할 때 및 스프링 시스템 실패.

스프링 기반 Java EE 시스템에서는 해시 인코더를 md5로 사용하고 소금을 변수로 사용합니다 (WnvTroeiBmd5bjGmmsVUnNjppadH7giK).

Junit 코드 단편 : 이 테스트 사례는 실패합니다.

@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

봄의 Md5PasswordEncoder는 줌라의 소금에 절인 MD5 암호와 호환 주장하지 않습니다.

즉, 작동하지 않습니다. Joomla가하는 것과 똑같은 일을하는 Java 코드가 필요합니다.

http://forum.joomla.org/viewtopic.php?t=207689#p993378이 코드 조각이라고 주장하면 시도해야합니다.

비슷한 문제가 발생하지 않는 경우 인코딩 문제 일 수 있으므로 자바 문자열 (16 비트 문자)을 PHP 호환 바이트 표현으로 변환해야합니다.

또한 PBKDF2과 같은 강력한 암호 유도 함수로의 마이그레이션 경로를 고려해야합니다.

+0

그것은 this.Below 테스트 케이스를 해결하기 위해 거의 하루에 걸렸다는 공공 무효 testSpringMD5Functionality() { 문자열 md5MigratedPassword = @Test 작동 "3c57ebfec712312f30c3fd1981979f58 : WnvTroeiBmd5bjGmmsVUnNjppadH7giK"; String [] m = md5MigratedPassword.split (":"); Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder(); passwordEncoder.setEncodeHashAsBase64 (false); 부울 값 = passwordEncoder.isPasswordValid (m [0] + m [1], "password", null); 어설트 트루 (값); // 테스트 케이스 패스 } – challenge

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();  
    } 
}