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



этот вопрос уже есть ответ здесь:



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

Имя пользователя и пароль для базы данных хранятся в файле свойств.

Какова общая практика, чтобы избежать хранения пароль в открытом тексте в файле свойств, сохраняя при этом возможность позволить пользователю изменить его?

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

Я читал здесь, что есть встроенный способ сделать это в C#.

Зная java, я не ожидаю найти встроенное решение, но я хотел бы услышать, что делают другие люди.

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



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

468   4  

4 ответов:

enter image description here

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

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

С помощью орг.jasypt.свойства.EncryptableProperties объект, приложение будет уметь правильно читать и использовать .файл свойств вот так:

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"...

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

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

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

частная строка pass1 = "TAKqWskc4ncvKaJTyDcgAHq82"

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

java-jar / myapplication.jar-pass2 X7tX6GfK2fc386bmNw3muknjU

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

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

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

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

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

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

Как насчет предоставления пользовательского механизма N-факторной аутентификации?

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

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

2) хранить в a .свойства файла

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

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

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

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

7) много альтернатив (например, нарисовать секрет, отпечаток пальца, IP-специфичный, бла-бла-бла)

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

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

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

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

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

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

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

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

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

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

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

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

на самом деле, это дубликат шифровать пароль в конфигурационных файлах?.

лучшее решение, которое я нашел до сих пор в этом ответе:https://stackoverflow.com/a/1133815/1549977

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

Comments

    Ничего не найдено.