Md5 с солевым кодированием

Я переношу некоторые данные из системы cms на основе joomla в среду Java EE на основе Spring.

В ходе анализа я обнаружил, что реализация паролей md5 отличается от joomla ??? Любая идея, почему разница в реализации md5 ??

Например: если в записи joomla было поле пароля, такое как «3c57ebfec712312f30c3fd1981979f58:WnvTroeiBmd5bjGmmsVUnNjppadH7giK» (здесь 3c57ebfec712312f30c3fd1981979f58 - окончательный хеш-дайджест md5, а WnvTroeiBmd5bjGmmsVUnNjppadH7giK - ключ, который должен быть добавлен с вводом пароля пользователя), и когда пользователь пытается войти в систему с этой записью в весенней системе, это не удается.

В системе Java EE на основе Spring мы используем хеш-кодировщик как 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 ?????

}

person Sekhar    schedule 09.02.2012    source источник


Ответы (2)


Md5PasswordEncoder Spring никогда не утверждал, что совместим с солеными паролями MD5 Joomla.

Короче не может работать. Вам нужен код Java, выполняющий то же самое, что и код Joomla.

http://forum.joomla.org/viewtopic.php?t=207689#p993378 утверждает, что это такой кусок кода, вам стоит попробовать.

Если это не работает, скорее всего, виновником является проблема с кодировкой, вы должны убедиться, что преобразовали строку Java (символы шириной 16 бит) в совместимое с PHP байтовое представление.

Также вам, вероятно, следует рассмотреть возможность перехода к более надежной функции получения паролей, такой как PBKDF2.

person Bruno Rohée    schedule 10.02.2012
comment
Мне потребовался почти день, чтобы исправить это. Ниже тестовый пример работает @Test public void testSpringMD5Functionality () {String md5MigratedPassword = 3c57ebfec712312f30c3fd1981979f58: WnvTroeiBmd5bjGmmsVUnNjppadH7giK; Строка [] m = md5MigratedPassword.split (:); Md5PasswordEncoder passwordEncoder = новый Md5PasswordEncoder (); passwordEncoder.setEncodeHashAsBase64 (ложь); логическое значение = passwordEncoder.isPasswordValid (m [0] + m [1], пароль, ноль); assertTrue (значение); // тестовый пример пройден} - person Sekhar; 11.02.2012

Вышеупомянутое не работает (включая комментарий по вызову). Следующий код взят отсюда - 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();      
   }
}
person alvins    schedule 06.03.2012