Вопрос по java – Защита пароля в файле свойств [дубликат]

58

This question already has an answer here:

Encrypt Password in Configuration Files? [closed] 10 answers

У меня есть Java-приложение, которое подключается к базе данных.
Имя пользователя и пароль для базы данных хранятся в файле свойств.
Какова общая практика, позволяющая избегать сохранения пароля в виде открытого текста в файле свойств при сохранении опции, позволяющей пользователю изменять его?
Основная мотивация здесь состоит в том, чтобы не дать кому-либо заглянуть через плечо администратора и увидеть пароль, пока администратор редактирует файл свойств.
Я читаюВот что есть встроенный способ сделать это в C #.
Зная Java, я не ожидаю найти встроенное решение, но мне бы хотелось услышать, что делают другие люди.
Если я не найду хорошего выбора, то, вероятно, собираюсь зашифровать его постоянным паролем, который будет храниться в коде. Но я не хочу делать это так, потому что это неправильно.

Edit Dec 12th 2012 Похоже, нет волшебства, и я должен хранить пароль в коде или что-то подобное. В конце мы реализовали нечто очень похожее на то, что делает Jasypt, который был упомянут в одном из ответов. Поэтому я принимаю ответ Ясыпта, потому что он ближе всего подходит к определенному ответу.

@ userunknown, очевидно, что для доступа к базе данных приложению Java необходимо иметь собственное имя пользователя и пароль. Они хранятся в файле свойств, как объяснил оригинальный постер. ZeroOne
Расшифровка его с помощью постоянного пароля, который хранится в коде, кажется законным способом сделать это, если люди, заглядывающие через плечо администратора, являются главной угрозой. ZeroOne
Я создал библиотеку с открытым исходным кодом: Secured-properties.brabenetz.net Пожалуйста, дайте мне знать, что вы об этом думаете. brabenetz
Сколько людей имеют доступ к базе данных? Разве им не нужен пароль для доступа к основной базе данных? Почему вы должны хранить второй / этот? user unknown
Лучшее, на что вы можете надеяться - это запутывание, если программа может его прочитать, любой, кто имеет доступ к файлам, может это сделать. Это не значит, что вы не можете сделать его чертовски сложным. lynks

Ваш Ответ

4   ответа
0

Зашифровать пароль в конфигурационных файлах?.

Лучшее решение, которое я нашел на данный момент, заключается в следующем:https: //stackoverflow.com/a/1133815/154997

Pros: пароль сохраняется в массиве символов, а не в виде строки. Это все еще не хорошо, но лучше, чем все остальное.

44

Jasypt предоставляет Org.jasypt.properties.EncryptableProperties класс для загрузки, управления и прозрачного дешифрования зашифрованных значений в файлах .properties, что позволяет смешивать как зашифрованные, так и незашифрованные значения в одном файле.

http: //www.jasypt.org/encrypting-configuration.htm

Используя объект org.jasypt.properties.EncryptableProperties, приложение сможет правильно читать и использовать файл .properties, например:

datasource.driver=com.mysql.jdbc.Driver 
datasource.url=jdbc:mysql://localhost/reportsdb 
datasource.username=reportsUser 
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm) 

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

Как мы читаем это значение? так

/*
* First, create (or ask some other component for) the adequate encryptor for   
* decrypting the values in our .properties file.   
*/  
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();     
encryptor.setPassword("jasypt"); // could be got from web, env variable...    
/*   
* Create our EncryptableProperties object and load it the usual way.   
*/  
Properties props = new EncryptableProperties(encryptor);  
props.load(new FileInputStream("/path/to/my/configuration.properties"));

/*   
* To get a non-encrypted value, we just get it with getProperty...   
*/  
String datasourceUsername = props.getProperty("datasource.username");

/*   
* ...and to get an encrypted value, we do exactly the same. Decryption will   
* be transparently performed behind the scenes.   
*/ 
String datasourcePassword = props.getProperty("datasource.password");

 // From now on, datasourcePassword equals "reports_passwd"...
Так что, в принципе, теперь пароль жестко задан в программе? mazaneicha
«Пароль», который вы видите в примере, используется для выполнения шифрования / дешифрования значений. В этом примере он жестко запрограммирован, но его можно получить из любого места (например, переменная окружения). Однако значения свойств, которые вы не хотите хранить в виде обычного текста, равны Зашифрованное и затем расшифровывается при прочтенииgetProperty() метод. В основном это слой запутанности, но он решает проблему серфинга на плечах и случайного доступа к конфиденциальным данным в состоянии покоя. Mads Hansen
@ MadsHansen Спасибо за информацию. Я не думаю, что буду использовать его для этого проекта (уже слишком далеко от замораживания кода ...), но я наверняка запомню его для следующей версии / проекта. daramasala
@ Рохит - взгляни на Github.com / ulisesbocchio / jasypt-весна-загрузка чтобы увидеть, что они сделали, и если вы сможете использовать Mads Hansen
@ Kedron вы можете сделать это следующим образом: StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor (); encryptor.setPassword ( "Абхинав"); String encryptedPassword = encryptor.encrypt ("abc @ 123"); System.out.println (encryptedPassword); if ("abc @ 123" .equals (encryptor.decrypt (encryptedPassword))) {System.out.println ("Success"); } else {System.out.println ("Сбой"); } gladiator
10

ного мультивалютного подхода.

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

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

private String pass1 = "TAKqWskc4ncvKaJTyDcgAHq82"

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

java -jar /myapplication.jar -pass2 X7tX6GfK2fc386bmNw3muknjU

Когда приложение запускается, оно использует pass1 + pass2 и подключается к базе данных.

Это решение имеет много преимуществ без упомянутых недостатков.

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

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

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

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

Это может быть небезопасно. Предоставление учетных данных через командную строку обычно не рекомендуется из-за регистрации в ОС. Злоумышленник просто откроет исходный файл -> прочитает половину пароля и наберетhistory в командной строке и вуаля! Konstantinos Chalkias
Это «лучше», но я согласен с комментатором K.C ......... все еще можно найти с большой настойчивостью. granadaCoder
8

or?

Прежде чем комбинировать доступные методы, давайте предположим, что мы можем выполнить следующее:

1) Жесткий код внутри Java-программы

2) Хранить в файле .properties

3) Попросить пользователя ввести пароль из командной строки

4) Попросите пользователя ввести пароль из формы

5) Попросите пользователя загрузить файл пароля из командной строки или формы

6) Введите пароль через сеть

7) много альтернатив (например, Draw A Secret, отпечаток пальца, IP-адрес, бла-бла-бла)

1-й вариант: Мы могли бы усложнить задачу для злоумышленника, используя запутывание, но это не считается хорошей контрмерой. Хороший кодер может легко понять, как он работает, если он / она может получить доступ к файлу. Мы могли бы даже экспортировать бинарный файл для каждого пользователя (или только часть обфускации или ключевую часть), поэтому злоумышленник должен иметь доступ к этому пользовательскому файлу, а не к другому дистрибутиву. Опять же, мы должны найти способ изменить пароли, например, перекомпилировать или использовать отражение для изменения поведения класса «на лету».

2-й вариант: Мы можем сохранить пароль в файле .properties в зашифрованном формате, чтобы он не был виден злоумышленнику напрямую (как и Jasypt делает). Если нам нужен менеджер паролей, нам также потребуется мастер-пароль, который снова должен храниться где-то - внутри файла .class, хранилища ключей, ядра, другого файла или даже в памяти - у всех есть свои плюсы и минусы.
Но теперь пользователи будут просто редактировать файл .properties для смены пароля.

3-й вариант: введите пароль при запуске из командной строки, напримерjava -jar /myprogram.jar -p sdflhjkiweHIUHIU8976hyd.

Это не требует сохранения пароля и останется в памяти. Тем не мение,history команды и журналы ОС, может быть, ваш злейший враг здесь. Чтобы изменить пароли на лету, вам нужно будет реализовать некоторые методы (например, прослушивать консольные входы, RMI, сокеты, REST-бла-бла-бла), но пароль всегда будет оставаться в памяти.

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

4-й вариант: введите пароль из пользовательской формы, а не из командной строки. Это позволит обойти проблему регистрации воздействия.

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

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

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

Мы не можем быть защищены от несанкционированного доступа в память, однако, это может быть достигнуто только с помощью некоторых аппаратных средств с ограниченным доступом (например, смарт-карт, HSM, SGX), где все вычисляется в них, без кого-либо, даже законного владельца возможность доступа к ключам дешифрования или алгоритмам. Опять же, это оборудование тоже можно украсть, сообщается атаки по боковому каналу это может помочь злоумышленникам в извлечении ключей, а в некоторых случаях вам нужно доверять другой стороне (например, с SGX вы доверяете Intel). Конечно, ситуация может ухудшиться, когда клонирование в защищенном анклаве (де-сборка) будет возможно, но я думаю, что на практике это займет несколько лет.

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

Мы всегда должны помнить, что каким бы ни был метод ввода, мы должны гарантировать, что мы не уязвимы от перехвата сети (MITM-атак) и / или клавиатурных шпионов.

Похожие вопросы