Я читал о java.io.Console
класс в одной из книг сертификации Java, возможно я пропустил что-то фундаментальное из предыдущей главы, но кто-то может объяснить ниже?
Это упоминает, что readPassword
метод возвращает символьный массив вместо Строки, чтобы препятствовать тому, чтобы потенциальный хакер нашел эту Строку и затем нашел пароль.
Как символьный массив более безопасен? Если Вы могли бы получить значения в массиве затем разве, Вы не могли бы создать сценарий, чтобы циклично выполниться через различные комбинации и в конечном счете найти пароль так или иначе?
Объект Console поддерживает безопасный ввод пароля с помощью своего метода readPassword. Этот метод помогает защитить ввод пароля двумя способами. Во-первых, он подавляет эхо, поэтому пароль не отображается на экране пользователя. Во-вторых, readPassword возвращает массив символов, а не строку, поэтому пароль можно перезаписать, удалив его из памяти, как только он больше не нужен.
Идея заключается в том, что вы можете вызвать Arrays.fill (или эквивалент), чтобы «очистить» массив символов, как только вы подтвердите пароль, и с этого момента пароль больше не будет хранится в памяти. Поскольку строки неизменяемы, строка будет оставаться в куче до тех пор, пока она не будет собрана мусором - что, если ей удастся интернировать себя, никогда не будет, и в любом другом случае все еще может быть «слишком длинным». Пока он существует, он потенциально уязвим для сниффинга с различных векторов.
String является неизменяемым классом, и когда пароль хранится в строка, которую вы не контролируете ее жизненный цикл, что означает, что она может быть доступна в памяти (и подвергаться дампам памяти и т.п.) в течение длительного времени (даже если она не интернирована, где она будет в памяти до тех пор, пока JVM выходов). Когда он хранится в массиве символов, вы можете очистить массив и, таким образом, удалить пароль из памяти после его проверки.
Это одна из лучших практик. В этом нет особого смысла, но мы делаем это для легкой жизни.
Если пароль находится в памяти, переполнение буфера может позволить его прочитать. Или его можно сохранить в виде дампа ядра или образа гибернации. Использование изменяемого char []
позволяет уничтожить данные после, надеюсь, узкого окна, пока они не были скопированы в строку, скопированы в другом месте, вероятно, в буферах, сборка мусора любит перемещать объекты и т. д.
В Swing есть забавный пример, где JPasswordField
предоставляет способ char []
для чтения данных, но, например, создает Строка
из данных, если у нее есть прослушиватель действий (что является очень распространенным способом его использования).