2013-05-19 2 views
4

Я хотел бы знать, правильна ли моя текущая реализация BCrypt, я знаю, что я не использую BCrypt.checkpw(), что может привести к проблеме, так что это основная причина, по которой я проверяю ее здесь.Java: Является ли это хорошим использованием BCrypt?

Hasher.java контейнерный класс:

abstract public class Hasher { 
    public static String hash(final char[] input) { 
     String output = Hasher.hash(new String(input)); 
     for (int i = 0; i < input.length; i++) { 
      input[i] = 0; 
     } 
     return output; 
    } 

    public static String hash(final String input) { 
     return BCrypt.hashpw(input, BCrypt.gensalt()); 
    } 
} 

Одна из проблем здесь: JPasswordField дает мне char[] по соображениям безопасности, однако BCrypt.hashpw() принимает только строки. Как я могу избежать того, чтобы String плавала в моей памяти?

Реализация клиент входа в систему:

String hashedPassword = Hasher.hash(password); 
Network.getInstance().send("login " + username + " " + hashedPassword); 

Так хэш отправляется по сети, в настоящее время сеть не зашифрована, но я планирую добавив, что.

Реализация сервера на создание учетной записи:

public static Account createAccount(final String username, final String password) { 
    String hashedPassword = Hasher.hash(password.toCharArray()); 
    return new Account(username, hashedPassword); 
} 

Реализация сервера проверки пароля:

public boolean checkPassword(final String hashedPassword) { 
    return this.hashedPassword.equals(hashedPassword); 
} 

С this.hashedPassword является хэш, который находится в памяти сервера (который поступает из базы данных по Bootup).

Свойства моей установки:

  • Вход в занимает значительное время клиента, так как пароль хешируется там.
  • Создание учетной записи/Изменение пароля занимает значительное время сервера, так как тогда пароль хешируется на сервере.
  • Проверка попыток входа в систему берет сервер практически без какого-либо времени, так как не требуется никакого хеширования.
  • Если кто-то доставит базу данных, содержащую хеши, то потребуется значительное время, чтобы взломать пароль для каждой учетной записи.
  • Мне все еще нужно найти хороший коэффициент работы для BCrypt.gensalt().

Пожалуйста, проверьте мои предположения.

С уважением.

+0

Чтобы проверить предоставленный пароль, вам необходимо записать его с той же солью, что и сохраненный. – Gumbo

+1

Соль хранится внутри «хэша» (хэш хэширования на самом деле больше, чем просто хеш), разве это не покрыло бы часть проверки? – skiwi

+0

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

ответ

10

Есть пара проблем с этой настройкой.

1) Соль должна представлять собой случайное генерирование во время процесса хеширования (как представляется, в вашей реализации. Поскольку клиент не имеет доступа к базе данных хранящихся хэшей, клиент не будет знать, какая соль использование при создании хэша входа.

2) Эта реализация на самом деле не проверяет пароль, переданный клиентом, он проверяет хэш пароля, переданный клиентом. Это означает, что если кто-то получит вашу базу данных хешей, они могут сразу использовать эти хэши для входа. Тогда не нужно взламывать их, чтобы извлекать пароли, так как вы не проверяете пароли.

Обе эти проблемы могут быть легко решены путем перемещения всей стороны хеширующего сервера.

Update

Что касается вопросов, которые вы упомянули.

1) Если у вас есть намерение создать безопасную систему, вы должны использовать SSL/TLS. Отправка хэшей паролей в ящике почти так же небезопасна, как отправка паролей в ящик. Оба - ужасная идея. Используйте HTTPS.

2) Выполнение хэширования на стороне сервера - довольно обычная практика. Процесс хеширования является достаточно дорогостоящим, чтобы сделать исчерпывающий поиск нецелесообразным, но он не должен мешать вашему процессу проверки подлинности. Если вы действительно обеспокоены тем, что DoSed, отслеживайте, сколько раз данный пользователь пытался войти в систему за последние N секунд. Если они провалились определенное количество раз, заблокируйте их учетную запись.

+0

Две проблемы с хэш-сервером (что я пытался адресовать, но не удалось до сих пор, не уверен, что невосстановимо, хотя): 1) мне нужно будет отправить пароль довольно много текста по сетевому каналу и 2) Это наложило бы большой упор на сервер при попытке входа в систему, моя текущая настройка (если работа) была бы идеальной для противодействия DDoS-атаке, ориентированной на страницу входа. – skiwi

+0

См. Обновленный ответ. – Aurand

+0

+1 хороший ответ. – Steve

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