2015-05-31 1 views
3

Как бы один идти о преобразовании обугленного [] пароль, полученный с помощью этого метода:Генерация MD5 Hash с гольца []

char[] password = passwordInputField.getPassword(); 

К MD5 Hash? Обычно я хотел бы использовать метод ниже, но GetBytes совместит только со строками:

MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update(password.getBytes()); 
String hashedPass = new BigInteger(1, md.digest()).toString(16); 
+0

Не уверен, что вы приложение, но MD5, как правило, не используется в целях безопасности больше. –

+0

Итак, что бы вы посоветовали использовать? –

+1

Предполагая, что вы хотите хранить и проверять пароль при регистрации, [bcrypt] (https://en.wikipedia.org/wiki/Bcrypt) является сегодня [стандартным] (http://www.javacodegeeks.com/) 2012/08/Bcrypt-соль-ее-голое minimum.html). См. [Этот вопрос] (https://security.stackexchange.com/questions/21184/safe-to-use-jbcrypt-and-recommend-it-to-my-organization) для реализаций Java. –

ответ

1

Примечание: MD5-хэширования алгоритм никогда не должен использоваться для хранения паролей, так как это хэш легко взломаны. Однако я буду использовать его для простоты.

Решение fast/easy/UNSECURE предназначено для преобразования массива char в строку. Однако это небезопасно, потому что строки неизменяемы и не могут быть очищены от памяти.

String password = new String(passwordInputField.getPassword()); 

MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update(password.getBytes()); 
String hashedPass = new BigInteger(1, md.digest()).toString(16); 

Более безопасное решение: преобразовать символ [], чтобы байт [] и очистить массивы из памяти после этого.

private byte[] toBytes(char[] chars) { 
    CharBuffer charBuffer = CharBuffer.wrap(chars); 
    ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer); 
    byte[] bytes = Arrays.copyOfRange(byteBuffer.array(), 
      byteBuffer.position(), byteBuffer.limit()); 
    Arrays.fill(charBuffer.array(), '\u0000'); // clear sensitive data 
    Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data 
    return bytes; 
} 

char[] passChars = passwordInputField.getPassword(); 
byte[] passBytes = toBytes(passChars); 

MessageDigest md = MessageDigest.getInstance("MD5"); 
md.update(passBytes); 
String hashedPass = new BigInteger(1, md.digest()).toString(16); 

Arrays.fill(passChars, '\u0000'); // clear sensitive data 
Arrays.fill(passBytes, (byte) 0); // clear sensitive data 

EDIT:

Обновленный ответ с более безопасным решением (кредитом user2656928 за идею). в andreyne

char[] to byte[] method кредит

+1

Быстро и легко, да. Но 'getPassword()' возвращает 'char []' для [соображений безопасности] (http://stackoverflow.com/q/8881291/4125191). Следует помнить об этом при обработке паролей. – RealSkeptic

+0

Это будет противоречить соображениям безопасности, почему swing возвращает пароль как 'char []' вместо 'String', а именно, что строки неизменяемы, поэтому, создав один, нет способа стереть его из памяти. С помощью 'char []' вы можете перезаписать данные, как только вы закончите с ним (за исключением того, что GC разрешено перемещать объекты и не может рассчитывать на стирание оригинала, если это так). Если вам нужна безопасность, вам действительно нужно найти или написать 'char []' to 'byte []' конвертер и сгладить оба массива позже. –

+2

@RealSkeptic, вы не ошибаетесь, но если этот хеш MD5 напрямую передается или хранится для какой-либо цели безопасности, тогда общая система имеет большую проблему, чем выделенная строка, задерживающая в памяти какое-то время. – Barend