Вопрос-ответ

Why is char[] preferred over String for passwords?

Почему char[] предпочтительнее строки для паролей?

В Swing поле пароля имеет метод getPassword() (returns char[]) вместо обычного метода getText() (returns String). Аналогичным образом, я наткнулся на предложение не использовать String для обработки паролей.

Почему String представляет угрозу безопасности, когда дело доходит до паролей? Кажется неудобным использовать char[].

Переведено автоматически
Ответ 1

Строки неизменяемы. Это означает, что после создания String, если другой процесс может выгрузить память, нет никакого способа (кроме отражения), которым вы можете избавиться от данных до того, как начнется сборка мусора.

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

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

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

Ответ 2

Хотя другие предложения здесь кажутся обоснованными, есть еще одна веская причина. С plain String у вас гораздо больше шансов случайно напечатать пароль в журналах, мониторах или в каком-либо другом небезопасном месте. char[] менее уязвим.

Учтите это:

public static void main(String[] args) {
Object pw = "Password";
System.out.println("String: " + pw);

pw = "Password".toCharArray();
System.out.println("Array: " + pw);
}

С принтами:

String: Password
Array: [C@5829428e
Ответ 3

Цитируя официальный документ, в руководстве по архитектуре криптографии Java говорится следующее о char[] сравнении String паролей (о шифровании на основе паролей, но это, конечно, в более общем плане о паролях):


Казалось бы логичным собирать и хранить пароль в объекте типа java.lang.String. Однако вот предостережение: Objectтипы String неизменяемы, т. Е. Не определены методы, которые позволяют изменять (перезаписывать) или обнулять содержимое a String после использования. Эта функция делает String объекты непригодными для хранения конфиденциальной информации, такой как пароли пользователей. Вместо этого вы всегда должны собирать и хранить конфиденциальную информацию в char массиве.


В руководстве 2-2 по безопасному кодированию для языка программирования Java версии 4.0 также говорится нечто подобное (хотя изначально это относится к ведению журнала):


Руководство 2-2: не регистрируйте высокочувствительную информацию


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


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


Ответ 4

Массивы символов (char[]) можно очистить после использования, установив каждому символу значение ноль, а строкам - нет. Если кто-то каким-то образом может видеть образ в памяти, он может видеть пароль в виде обычного текста, если используются строки, но если используется char[], после очистки данных с помощью 0 пароль защищен.

2024-02-27 12:50 java string