Как лучше всего безопасно хранить пароли на Java

Каким будет рекомендуемый способ хранения паролей в настольном приложении Java?

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

В личных проектах я использую Preferences API, но предполагаю, что это ничем не отличается от его хранения в виде обычного текста (с точки зрения безопасности).

Большое спасибо

РЕДАКТИРОВАТЬ:

Большое спасибо за ваши предложения. Кажется, есть некоторая путаница, без сомнения, потому что я, возможно, не очень четко сформулировал вопрос ...

Приведу гипотетический сценарий:

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

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

Что-то вроде функции «запомнить меня» (которая, как я знаю, сама по себе не очень хорошая практика ...)

РЕДАКТИРОВАТЬ2:

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


person Rui Vieira    schedule 10.08.2011    source источник
comment
Взгляните на этот вопрос: stackoverflow.com/q/6592010/313205   -  person Marcelo    schedule 11.08.2011
comment
Пожалуйста, не переходите по ссылке Марсело. Там полно плохих советов. Проверьте ответ и прочтите статью codahale. То, что было хорошим советом 10 лет назад, стало небезопасным за последние 5 лет, потому что мы можем легко перебрать эти алгоритмы с небольшими инвестициями в компьютерное оборудование. SHA1, MD5 и пароли длиной до 8 символов со всеми символами (a-z, A-Z, 0-9, специальные символы) легко взломать.   -  person chubbsondubs    schedule 11.08.2011
comment
+1 за не SHA1 / MD5. Как я писал ниже, некоторые eejit обиделись.   -  person Deleted    schedule 11.08.2011
comment
Вы говорите о вводе пароля для вашего собственного приложения или хранении паролей к внешним системам, таким как база данных или веб-сервис?   -  person Affe    schedule 11.08.2011
comment
Сначала вам нужно описать, от кого вы хотите защитить.   -  person CodesInChaos    schedule 11.08.2011
comment
@CodesInChaos Все, кто не мы, - враги. - любая программа, кроме его приложения, не должна получать пароль.   -  person Tomáš Zato - Reinstate Monica    schedule 18.03.2015


Ответы (3)


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

Ответ для редактирования:

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

person Jérôme Verstrynge    schedule 10.08.2011
comment
У этого вопроса 8000 просмотров. В вашем ответе 6 строк (изначально была только одна) по сложной теме безопасности. Ты серьезно? Ответы на подобные вопросы, как правило, вызывают гораздо больше голосов (и строк). Что такое хранилище ключей? Как это используется? Это Java или ОС? Хотел бы я проголосовать против каждого вопроса, поднятого вашим ответом. - person Tomáš Zato - Reinstate Monica; 18.03.2015
comment
@ TomášZato Это вопрос Java, хранилища ключей - это основная функция Java SSE (Secure Socket Extension). Несмотря на все взгляды на этот вопрос, у него не так много положительных голосов. - person Raystorm; 27.04.2015
comment
@Raystorm Для всех представлений, которые имеет этот вопрос, у этого ответа не так много положительных голосов. - Это то, что я указывал. - person Tomáš Zato - Reinstate Monica; 27.04.2015
comment
Да, этот ответ мог бы содержать гораздо больше деталей и быть намного более полезным. ;) - person Geoffrey Wiseman; 02.08.2016

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

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

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

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

person Paŭlo Ebermann    schedule 10.08.2011
comment
да, но алгоритм дешифрования может быть привязан к времени в Интернете, что было бы огромной проблемой для выяснения. - person Solomon P Byer; 03.07.2015
comment
Использование системных разрешений может помочь, если у злоумышленника нет root-доступа. - person Brian McCutchon; 02.02.2017
comment
@BrianMcCutchon, если злоумышленник также работает под той же учетной записью, что и ваша программа Java, оба имеют одинаковые привилегии и могут обращаться к одним и тем же файлам. Конечно, злоумышленник может получить доступ к любым файлам. - person Paŭlo Ebermann; 02.02.2017
comment
@ PaŭloEbermann Нет, если ОС контролирует, какие приложения могут получать доступ к паролям, как, например, связка ключей MacOS. В связке ключей MacOS приложение может использовать создаваемые им пароли и пароли, к которым пользователь явно предоставляет ему доступ. См. Здесь: developer.apple.com/library / content / documentation / Security / - person Brian McCutchon; 03.02.2017
comment
@BrianMcCutchon Хорошо, я ничего не знаю о том, как работает MacOS ... можете ли вы зарегистрировать программу Java в качестве приложения (вместо того, чтобы просто использовать интерпретатор Java в качестве приложения)? - person Paŭlo Ebermann; 04.02.2017
comment
Вы можете полностью создать приложение Java Mac с помощью одного из инструментов сборщика приложений, доступных для Maven или Ant. - person Brian McCutchon; 05.02.2017

Я думаю, что это применимо независимо от языка: http://codahale.com/how-to-safely-store-a-password/

Таким образом, используйте хеш-функцию bCrypt.

Реализация API настроек зависит от памяти, поэтому вы будете во власти поставщика JVM. Если это Sun / Oracle JVM, получить данные тривиально. Однако, если вы его хешируете и применяете приличную политику паролей, это будет очень безопасно. Исходный пароль будет очень сложно определить.

person Deleted    schedule 10.08.2011
comment
хеширование пароля не позволяет его восстановить. - person Jérôme Verstrynge; 11.08.2011
comment
Err, почему вы хотите восстановить пароль? Это просто бред. - person Deleted; 11.08.2011
comment
Я хочу, чтобы пользователь имел возможность вводить учетные данные только один раз и больше не запрашивался. - ›Это означает, что пароль будет использоваться повторно. - person Jérôme Verstrynge; 11.08.2011
comment
Я думаю, что непонятным моментом является то, что кажется, что OP действительно хочет сохранить пароль для какой-то сторонней системы, например, его строку подключения к базе данных безопасно, чтобы он мог программно отправить его позже. Не предполагается, что внешняя система имеет API, который принимает уже хешированный пароль по произвольному алгоритму! - person Affe; 11.08.2011
comment
@JVerstry: Нет, это неправильно. Повторно используется хешированный пароль, а не нехешированный. Вы хешируете его заранее, а затем сравниваете хэш каждый раз, когда вам нужно проверить учетные данные. Если вам нужно поговорить с поставщиками, которые поддерживают разные алгоритмы хеширования, вы заранее сохраняете ВСЕ варианты, которые требуются вашим поставщикам или службам (SHA1, MD5, bCrypt и т. Д.). Если они говорят пароли в виде обычного текста, то возникают серьезные проблемы. - person Deleted; 11.08.2011
comment
@Chris Вопрос: какой способ хранения паролей в настольном приложении Java рекомендуется использовать? Это не об удаленных сервисах или поставщиках. - person Jérôme Verstrynge; 11.08.2011
comment
@JVerstry: я ответил. - person Deleted; 11.08.2011
comment
@Chris Если вы храните хеши паролей, это не решает проблемы, особенно если вы собираетесь их использовать. Сами хеши не защищены. При всем уважении, предлагаемое вами решение не является решением. Вы упускаете суть. - person Jérôme Verstrynge; 11.08.2011
comment
Хранение всего, что может быть напрямую использовано для аутентификации, позволит злоумышленникам войти в систему вместо вас. - person Paŭlo Ebermann; 11.08.2011
comment
Если это так, и это проблема, вам следует сохранить хешированный пароль в энергозависимом хранилище (памяти). Если это вектор атаки, не храните пароль. Я думаю, что люди делают эту проблему больше, чем она есть на самом деле :) - person Deleted; 11.08.2011
comment
Хранение хешированных паролей работает, если ваше приложение - единственное, что требует аутентификации (потому что вы можете просто хранить / сравнивать хешированные пароли, что очень безопасно). Однако, если пароли предназначены для другой системы, вам необходимо сохранить необработанный пароль. Хорошим примером может служить FTP-клиент: ему нужно хранить ваши необработанные пароли, потому что это то, что ему нужно передать серверу. - person ryvantage; 15.11.2013