Как надежно хранить хеши паролей в памяти при создании аккаунтов? - PullRequest
6 голосов
/ 14 марта 2009

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

Если быть более точным, как можно убедиться, что строка, содержащая пароль, является мусором в течение достаточно короткого промежутка времени?

Ответы [ 6 ]

6 голосов
/ 14 марта 2009

Если у вас есть такая возможность (может быть сложно в веб-приложениях), лучше хранить пароли в символьных массивах, чем хранить их в строках. Если вы закончили хранить пароль, вы можете перезаписать его в памяти с помощью Array.fill () и сделать ссылку доступной для сборщика мусора, отбросив ее:

Arrays.fill(password, ' ');
password = null;

Я только что заметил, что обнуление пароля будет немного параноидальным, но вы можете это сделать, если оно вас успокоит:)

5 голосов
/ 14 марта 2009

Вы не используете строку. Вы используете char [] и затем переписываете char [], когда закончите.

Нет абсолютно никаких гарантий, когда дело доходит до сбора мусора (кроме того, что финализатор запустится до того, как объект будет собран). GC может никогда не запуститься, если он запускается, он никогда не может GC String, в которой есть пароль.

3 голосов
/ 14 марта 2009

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

2 голосов
/ 14 марта 2009

Два слова: локальная сфера. Объявленные переменные для обработки пароля должны иметь минимально возможную область действия.

Как только переменные выходят из области видимости, объекты могут быть использованы для сборки мусора.

Часто вы выбираете вещи из запроса. Вам нужна очень маленькая транзакция, которая принимает запрос, хэширует пароль, сохраняет его и перенаправляет. Страница, на которую вы перенаправляете, может затем извлечь контент и выполнить всю «другую» обработку, которая является частью вашего приложения.

1 голос
/ 14 марта 2009

Нет способа гарантировать, что пароли в виде открытого текста будут удалены из памяти в Java.

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

Наилучший подход состоит в том, чтобы клиент шифровал пароль, как предлагает @ Mork0075. Однако, хотя это означает, что вы не можете легко получить пароль, программа все равно может получить зашифрованную версию паролей и, таким образом, притворяться пользователем. Обойти это можно путем шифрования всего соединения с использованием SSL.

Все это довольно академично, поскольку самый простой подход для хакера - отслеживать пакеты в базе данных и получать пароль для вашей базы данных. Я подозреваю, что прямой доступ к вашей базе данных больше касается ... или, возможно, это не так. ;)

0 голосов
/ 14 марта 2009

Использовать пароль:

  1. Сервер выбирает значение вызова и отправляет его Клиенту
  2. Сервер выполняет одностороннюю трансляцию с паролем и вызовом, напр. MD5(CONCAT(challenge, password)) и назначает его сеансу.
  3. Обычный текстовый пароль теперь находится вне области и готов для сбора мусора.
  4. Клиент также выполняет тот же перевод и отправляет результат на Сервер.
  5. Если сервер и клиент выбирают одно и то же конечное значение, клиент аутентифицируется.

Этот метод предотвращает повторных атак , но требует, чтобы значение вызова было очень непредсказуемым (случайным) и не часто использовалось (длинным).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...