2014-02-17 3 views
1

Является ли моя реализация хэширования паролей Salting и SHA-512 правильной/безопасной?Является ли правильная/безопасная реализация хэширования паролей Salting и SHA-512?

Я знаю, что я должен повторять алгоритм пару раз на соленом пароле. Кроме того, что еще я должен реализовать, чтобы защитить его или этого достаточно?

 public static String[] SHA512(String password) 
{ 
    //Generates the salt 
    SecureRandom saltRandomizer = new SecureRandom(); 
    byte[] salt = new byte[64]; //The same size as the output of SHA-512 (512 bits = 64 bytes) 
    saltRandomizer.nextBytes(salt); 
    String encodedSalt = Base64.encodeToString(salt, Base64.DEFAULT); 


    //Prepends the salt to the password 
    String saltedPassword = encodedSalt + password; 

    //Hashed the salted password using SHA-512 
    MessageDigest digester; 
    byte[] digest = null; 
    try { 
     digester = MessageDigest.getInstance("SHA-512"); 
     digester.reset(); 
     digester.update(saltedPassword.getBytes()); 
     digest = digester.digest(); 
    } catch (NoSuchAlgorithmException e) { 
     System.out.println("No such algorithm"); 
     e.printStackTrace(); 
    } 

    String[] passwordPlusSalt = new String[2]; 
    passwordPlusSalt[0] = Base64.encodeToString(digest, Base64.DEFAULT); 
    passwordPlusSalt[1] = encodedSalt; 
    return passwordPlusSalt; 
} 

Заранее спасибо

+0

Не так уж плохо - если честно, я бы просто использовать [jBCrypt] (HTTP://www.mindrot.org/projects/jBCrypt/). Он касается хеширования с солью, хранения соли и последующей проверки. Написание всего этого кода немного похоже на игру с огнем. –

+1

Отсутствие итераций - большая ошибка. У вас должно быть 10000 итераций, а не просто «пара». (Если вы не поклонник * незначительных * преуменьшений). – CodesInChaos

ответ

6

Нет. Это не безопасно. Посмотрите на эту строку:

SecureRandom saltRandomizer = new SecureRandom(); 

Я замечаю, что вы не указываете PRNG или поставщика. Я не эксперт, но я понимаю, что SUN CSP по умолчанию - использовать sun.security.provider.NativePRNG для Solaris и Linux, который просто обеспечивает вывод/dev/urandom, который может (или может быть) быть подходящим для ваших нужд (он, например, не рекомендуется для генерации криптографических ключей).

Поэтому рекомендуется всегда указывать ПСЧ и поставщика, а именно:

SecureRandom.getInstance("SHA1PRNG", "SUN"); 

Кроме того, целесообразно:

  • Периодически выбрасывайте существующий экземпляр java.security.SecureRandom и создать новый. Это создаст новый экземпляр с новым семенем.
  • Периодически добавляйте новый случайный материал в семя PRNG, делая вызов java.security.SecureRandom.setSeed (java.security.SecureRandom.generateSeed (int)).

Точка зрения, которую я делаю, заключается в том, что безопасность - это сложная тема, которая настолько легко ошибается.Не пытайтесь и homebrew решение. Используйте существующую библиотеку. Чтобы привести отличный ответ Томаса Порнина:

Сложность - это плохо. Домашнее плохо. Новое плохо.

Источники:

+2

'/ dev/urandom' обычно подходит для генерации криптографических ключей. Повторное пересыщение тоже не так важно, но поскольку OP генерирует новый экземпляр для каждого вызова, он, конечно, довольно часто перекачивается. – CodesInChaos

+0

@CodesInChaos - Из wikipedia - '/ dev/urandom ... не рекомендуется для генерации долговременных криптографических ключей.' – hoipolloi

+0

Он использует его для соли - поэтому я не думаю, что криптографическая случайность - это необходимость. Черт, соль, как ожидается, будет утечка, когда хеши. –

2

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

  • не используется семенем для генерации случайных байт
  • не отслеживание сгенерированных случайных байт, чтобы использовать их для проверки пароля
  • с помощью конкатенации не добавляют алгоритмов ранжирования сложность, но выглядит как безопасность от неизвестности, которая оказалась неэффективной в критически важных средах безопасности.

Вместо этого используйте стандартный алгоритм HMAC, специально разработанный для ваших нужд. Список алгоритмов, поддерживаемых java 7, доступен here. PBKDF2WithHmacSHA1 - хороший выбор. Это просто может быть использован, как это:

PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8); 
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
byte[] secretPassword = skf.generateSecret(spec).getEncoded(); 

Полный рабочий код можно найти here. Он должен ограничивать влияние атаки грубой силы/dictionnary, если база данных паролей попадает в неправильные руки.

Обратите внимание, что соль является критическим кольцом. В зависимости от ваших требований безопасности вы можете сохранить его в отдельной файловой системе, ввести или загрузить его при запуске сервера. Там могут быть даже специализированные (и в целом дорогие) аппаратные модули безопасности, которые могут обеспечить безопасность.

+0

Было бы здорово, если бы вы могли извлечь важные части из источника, который вы цитируете, в случае, если ссылка станет недействительной в будущем. Если вы хотите поделиться только ссылкой, подумайте о том, чтобы опубликовать ее как комментарий. – dst

+0

Не могли бы вы уточнить, на каких частях вы ссылаетесь? Спасибо – Aurum

+0

@dst Вы правы. Я отредактировал свой ответ, чтобы добавить более подробную информацию и включить код snipplet. –

 Смежные вопросы

  • Нет связанных вопросов^_^