GuardedString и сохранение памяти с JVM - PullRequest
1 голос
/ 03 апреля 2019

Контекст

Недавно у меня была лекция по криптографии, и мы обсуждали сохранение критических элементов в памяти.Как правило, библиотека C / C ++ Libsodium предлагает очистить любой буфер, содержащий конфиденциальную информацию, например секрет ( ref ).Я знаю, что GuardedString поддерживается массивом байтов, и документы рекомендуют вызывать метод dispose, если сохраненный секрет больше не используется, который заполняет массив байтов, используя Arrays.fill.

Вопрос

Гарантирует ли JVM, что значения байтового массива исчезли при перезаписи или исходные значения могут остаться в памяти при определенных условиях?Например, неиспользуемые / не имеющие ссылки String сохраняются в пуле строк Java до тех пор, пока не будет запущена сборка мусора.Существуют ли подобные кэширование или механизмы для других типов, такие как байтовый массив, которые могут скомпрометировать секрет, который должен быть удален из GuardedString?Любая ссылка в спецификации JVM?

Большое спасибо!

1 Ответ

1 голос
/ 03 апреля 2019

В Java обычно используется массив char[] вместо String, поскольку это позволяет вручную обнулять данные в массиве.

Однако даже тогда данные могут быть не полностью сброшены в соответствии с этим ответом :

Как отмечалось в комментариях, вполне возможно, что массивы, перемещаемые сборщиком мусора, оставят в памяти случайные копии данных. Я полагаю, что это зависит от реализации - сборщик мусора может очистить всю память по мере необходимости, чтобы избежать подобных вещей. Даже если это произойдет, есть время, в течение которого char [] содержит действительные символы в качестве окна атаки.

Аналогичная проблема существует в C / C ++, если компилятор решает оптимизировать memset. Согласно 11,4. Особая защита секретов (паролей и ключей) в пользовательской памяти :

В сообщении Bugtraq Энди Полякова (7 ноября 2002 г.) сообщалось, что компиляторы C / C ++ gcc версии 3 или выше, SGI MIPSpro и компиляторы Microsoft исключили простые встроенные вызовы memset, предназначенные для перезаписи секретов. Это разрешено стандартами C и C ++. Другие компиляторы C / C ++ (например, gcc меньше, чем версия 3) сохранили встроенный вызов memset на всех уровнях оптимизации, показывая, что проблема связана с компилятором. Простое объявление о том, что данные назначения изменчивы, помогает не всем компиляторам; и компиляторы MIPSpro и Microsoft игнорировали простую «улетучивание». Простое «прикосновение» к первому байту секретных данных тоже не поможет; он обнаружил, что MIPSpro и GCC> = 3 умело сводят на нет только первый байт и оставляют остальные нетронутыми (что на самом деле довольно умно - проблема в том, что хитрость компилятора мешает нашим целям).

...