Почему в Java не следует использовать тип String для хранения паролей?

«Почему в Java не следует использовать тип String для хранения паролей?» — вопрос из категории Безопасность, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Класс String непригоден для хранения конфиденциальных данных (паролей, токенов) из-за особенностей управления памятью в JVM.

Проблемы с String:

  • Неизменяемость (Immutability): Нельзя перезаписать значение. Пароль останется в памяти до сборки мусора.
  • Пул строк (String Pool): Литералы и интернированные строки хранятся в пуле, что продлевает их жизнь и делает уязвимыми для утечек через дампы памяти.
  • Логирование: Случайная передача String в лог может привести к его записи в открытые файлы.

Решение: использовать char[]

char[] password = passwordField.getPassword();
try {
    // Аутентификация...
    authenticate(user, password);
} finally {
    // Немедленная очистка памяти
    Arrays.fill(password, '');
}

Преимущества char[]:

  1. Возможность ручной очистки массива нулями после использования.
  2. Не попадает в String Pool.
  3. Снижает риск утечки через дамп памяти.

Для хранения: всегда используйте адаптивные хеш-функции (bcrypt, scrypt, Argon2, PBKDF2), а не сырые пароли.