Подтвердить что ты не робот

Защита пароля в файле свойств

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

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

4b9b3361

Ответ 1

enter image description here

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

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

Используя объект 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"...

Ответ 2

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

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

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

private String pass1 = "TAKqWskc4ncvKaJTyDcgAHq82"

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

java -jar/myapplication.jar -pass2 X7tX6GfK2fc386bmNw3muknjU

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

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

7) множество альтернатив (например, Draw A Secret, Fingerprint, IP-specific, bla bla bla)

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

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

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

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

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

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

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

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

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

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

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

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