Создание схемы надежного пароля, когда все данные хранятся на устройстве - PullRequest
4 голосов
/ 15 декабря 2010

Справочная информация:
Я работал над приложением Android, которое хранит данные в локальной базе данных как мой любимый проект. В последнее время я решил, что хочу защитить приложение паролем и зашифровать базу данных. Теперь я знаю о сложностях шифрования базы данных на лету и (учитывая ожидаемую схему использования моего приложения) решил просто зашифровать весь файл базы данных, а не пытаться сохранить зашифрованное значение столбца или тому подобное. До сих пор я внедрил систему, которая будет запрашивать пароль при каждом запуске приложения или всякий раз, когда пользователь удаляется от моей активности (чтобы учесть, что пользователь нажимает клавишу «Домой», и приложение не удаляется своевременно).

В настоящее время я пытаюсь решить, как именно хэшировать пароль и где его хранить. Учитывая, что все должно храниться на устройстве, я в основном трактую хэши и соли паролей как уже скомпрометированные, так как любой, кто потратил 10 минут на чтение, может получить root права на данное устройство и получить доступ к моей базе данных / настройкам.

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

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

  1. Пароль открытого текста хешируется.
  2. Хешированный пароль запускается по тому же алгоритму контрольной суммы, который используется для стандартных штрих-кодов UPC. Это приведет к значению от 0 до 9 (включительно).
  3. Эта контрольная сумма будет использоваться в качестве индекса для массива значений солей. Это единственное значение соли будет добавлено к текущему хешу.
  4. Новое значение hash + salt будет затем хешировано, и шаги 2 - 3 будут повторены.

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

Теперь я понимаю, что это звучит как излишество для простого приложения для мобильного телефона. Это. Но, так как это мой любимый проект, почему бы и нет?

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

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

-cheers

Ответы [ 5 ]

5 голосов
/ 15 декабря 2010

Я не понимаю.Если вы шифруете базу данных, зачем вам где-то хранить хэш пароля?

Получите ключ шифрования из пароля, который хранится в мозгу пользователя, используя что-то вроде PBKDF2.Используйте его для шифрования базы данных.

Когда пользователь хочет расшифровать базу данных, запросите у него пароль.Снова извлеките из него ключ и расшифруйте базу данных.

Вы сохраняете хэш пароля для целей аутентификации.Но это шифрование, а не аутентификация.


Предположим, у вас есть хеш-функция, которая принимает соль, число итераций и пароль в качестве входных данных и возвращает хеш-код в качестве вывода: byte[] hash(byte[] salt, int count, char[] password).Произвольно сгенерируйте одну соль при первом запуске приложения и хэшируйте новый пароль.Сохраните эту соль и полученный хеш в настройках приложения.Затем случайным образом сгенерируйте еще одну соль и добавьте к ней пароль.Используйте полученный хеш в качестве ключа шифрования базы данных, но сохраняйте только новую соль в настройках приложения.

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

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

0 голосов
/ 15 декабря 2010

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

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

Но главная проблема с вашим подходом (IMO) - просто сложность.

0 голосов
/ 15 декабря 2010

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

0 голосов
/ 15 декабря 2010

Хорошо ... Если ваш метод хеширования не является слабым, не имеет значения, известна ли соль - Salt просто так, что 2 пользователя с одним и тем же паролем имеют разные хэши - и случайная проверка хэшей не будет В результате идентичные пароли будут очевидны. Соль должна быть уникальная на пользователя.

Предполагая, что (злонамеренный) пользователь имеет root, вы абсолютно ничего не можете сделать, чтобы он не скомпрометировал ваше приложение, кроме шифрования - в частности, пользователь может теоретически получить ваш двоичный файл, декомпилировать его, чтобы выяснить, как он аутентифицирует пользователей, обойти его и затем просто следуйте механизму дешифрования - и поскольку ключ шифрования не связан с пользователем PW в вашем сценарии, он должен храниться ГДЕ-ТО - и, если приложение может его прочитать, то и root может

Единственный действительно безопасный подход - это использование однопользовательского (или хотя бы одного пароля), связанного с ключом шифрования БД.

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

0 голосов
/ 15 декабря 2010

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

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

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