Безвозвратно уничтожая данные в Java - PullRequest
11 голосов
/ 23 сентября 2008

Есть ли в Java способ удалить данные (например, значение переменной, объект) и убедиться, что их невозможно восстановить из памяти? Удаляет ли значение null переменной в Java значение из памяти? Есть идеи? Ответы, применимые к другим языкам, также приемлемы.

Ответы [ 10 ]

19 голосов
/ 23 сентября 2008

Из-за чудесной виртуальной памяти практически невозможно удалить что-либо из памяти совершенно безвозвратно. Лучше всего обнулять поля значений; однако:

  • Это не означает, что старая (ненулевая) копия объекта не останется на неиспользованной странице подкачки, которая может сохраняться при перезагрузке.
  • Это также не мешает кому-либо подключить отладчик к вашему приложению и ковыряться в нем до того, как объект обнулится, или выйдет из строя виртуальной машины и покажет в дампе кучи.
9 голосов
/ 23 сентября 2008

Храните конфиденциальные данные в массиве, а затем обнуляйте их как можно скорее.

Любые данные в ОЗУ могут быть скопированы на диск системой виртуальной памяти. Данные в ОЗУ (или дамп ядра) также могут быть проверены средствами отладки. Чтобы свести к минимуму вероятность этого, вы должны стремиться к следующему

  • держать временное окно в секрете присутствует в памяти так коротко, как возможно
  • будьте осторожны с конвейерами ввода-вывода (например, BufferedInputStream), что внутренне буфер данных
  • хранить ссылки на секрет в стеке и вне кучи
  • не используйте неизменяемые типы, такие как String, чтобы хранить секреты

Криптографические API в Java используют этот подход, и любые создаваемые вами API также должны его поддерживать. Например, KeyStore.load позволяет вызывающему абоненту сбросить пароль char[], а после завершения вызова - KeySpec для шифрования на основе пароля.

В идеале вы должны использовать блок finally для обнуления массива, например:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream is = …
char[] pw = System.console().readPassword();
try {
 ks.load(is, pw);
}
finally {
  Arrays.fill(pw, '\0');
}
3 голосов
/ 23 сентября 2008

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

2 голосов
/ 23 сентября 2008

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

2 голосов
/ 23 сентября 2008

Установка вашего объекта на ноль не означает, что ваш объект удаляется из памяти. Виртуальная машина помечает этот объект как готовый для сборки мусора, если на него больше нет ссылок. В зависимости от вашего кода на него все еще можно ссылаться, даже если вы установили его в null, и в этом случае он не будет удален. (По сути, если вы ожидаете, что это будет сборка мусора, а не утечка памяти!)

Как только он помечен как готовый для сбора, вы не можете контролировать, когда сборщик мусора удалит его. Вы можете возиться со стратегиями сбора мусора, но я бы не советовал. Профилируйте свое приложение и посмотрите на объект и его идентификатор, и вы сможете увидеть, что на него ссылается. Java предоставляет VisualVM с 1.6.0_07 и выше или вы можете использовать NetBeans

1 голос
/ 23 сентября 2008

Если вы думаете о защите управления паролем / ключом, вы можете написать код JNI, который использует API для конкретной платформы для безопасного хранения ключей и не утечки данных в память, управляемую JVM. Например, вы можете сохранить ключи на странице, заблокированной в физической памяти, и запретить доступ к памяти шине ввода-вывода.

РЕДАКТИРОВАТЬ: Чтобы прокомментировать некоторые из предыдущих ответов, JVM могла бы перемещать ваши объекты в памяти, не стирая их прежние местоположения, поэтому даже char [], байты, int и другие «стираемые» типы данных не являются ответом если вы действительно хотите убедиться, что конфиденциальная информация не сохраняется в памяти, управляемой JVM, или не перезаписывается на жесткий диск.

1 голос
/ 23 сентября 2008

Примитивные данные (byte, char, int, double) и их массивы (byte [], ...) стираются путем записи в них нового случайного контента.

Данные объекта необходимо очистить, переписав их примитивные свойства; установка переменной в null просто делает объект доступным для GC, но не сразу мертвым. Дамп виртуальной машины будет содержать их на всеобщее обозрение.

Неизменяемые данные, такие как String, не могут быть перезаписаны никаким образом. Любая модификация просто делает копию. Вы должны избегать хранения конфиденциальных данных в таких объектах.

P.S. Если мы говорим о паролях, лучше использовать криптостойкие хеш-функции (MD5, SHA1, ...) и никогда не работать с паролями в открытом виде.

1 голос
/ 23 сентября 2008

Я думаю, что вам лучше всего (это не сложно) использовать char [], а затем менять каждую позицию в массиве. Другие комментарии о том, что это можно скопировать в память, все еще применяются.

1 голос
/ 23 сентября 2008

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

0 голосов
/ 23 сентября 2008

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

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

я получаю либо TinyShredder, либо используя CCleaner, установленный на проход Гутмана

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