Конфигурация Typesafe: шифрование/обфускация конфиденциальных значений в памяти

У меня есть проект Akka, для работы которого требуется несколько паролей: для доступа к хранилищу данных, строка подключения к распределенной файловой системе...

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

Мне просто интересно, опасно ли это как-то, так как я предполагаю, что строки будут очищены в памяти. Есть ли способ прозрачно запутать/зашифровать значения? Или мне нужно реализовать это на моей стороне и обновить третьи стороны, чтобы они преобразовывали строку, прежде чем фактически открывать соединения.


person CanardMoussant    schedule 28.03.2017    source источник


Ответы (2)


На мой взгляд, почти в каждом приложении это угроза безопасности, о которой вам не следует беспокоиться. Поскольку Scala работает на JVM, см.: Конфиденциальные данные в памяти.

person Federico Pellegatta    schedule 31.03.2017
comment
Что ж, к сожалению, мои коллеги не разделяют эту точку зрения :). Я читал в нескольких местах, что в Java безопаснее использовать массив байтов вместо строк, но здесь я полагаюсь на объекты конфигурации Typesafe для хранения данных :-(. - person CanardMoussant; 31.03.2017
comment
Можете ли вы дать несколько ссылок на эти несколько мест? - person Chrs; 31.03.2017
comment
stackoverflow.com/ вопросы/8881291/ - person Federico Pellegatta; 31.03.2017

Вы можете попробовать использовать sun.misc.Unsafe для очистки памяти сразу после ввода пароля:

    String password = new String("l00k@myHor$e");
String fake = new String(password.replaceAll(".", "?"));
System.out.println(password); // l00k@myHor$e
System.out.println(fake); // ????????????

getUnsafe().copyMemory(
          fake, 0L, null, toAddress(password), sizeOf(password));

System.out.println(password); // ????????????
System.out.println(fake); // ????????????

или через отражение:

Field stringValue = String.class.getDeclaredField("value");
stringValue.setAccessible(true);
char[] mem = (char[]) stringValue.get(password);
for (int i=0; i < mem.length; i++) {
  mem[i] = '?';
} 

http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

person Alex Chernyshev    schedule 06.04.2017
comment
Моя проблема в том, что пароль считывается третьей стороной из файла конфигурации, поэтому я не могу переопределить пароль в памяти после его использования. - person CanardMoussant; 06.04.2017
comment
конечно можно, например, после полного запуска приложения. - person Alex Chernyshev; 06.04.2017
comment
Что ж, пароль может понадобиться позже, если, например, необходимо выполнить повторное подключение. - person CanardMoussant; 06.04.2017
comment
зависит от реализации, может быть аутентификация сеанса, основанная на ключах сеанса и так далее. Что-то вроде этого vaultproject.io/docs/secrets/mysql - person Alex Chernyshev; 06.04.2017