Skip to content
Dev Dump

πŸ” Why use `char[]` over `String` for passwords in Java?

When handling sensitive data like passwords, security is a big concern. Java offers two common ways to store password input:

  • Using a String
  • Using a char[] (character array)

At first, both seem okay β€” but there are important security reasons why char[] is the preferred choice.

Aspectchar[]String
Mutableβœ… Yes❌ No (Immutable)
Can erase?βœ… Yes (overwrite with nulls)❌ No (stays in memory until GC runs)
Stored in Pool?❌ Noβœ… Yes (String pool)
Memory lifespanShorter (can control manually)Longer (waits for GC)
Securityβœ… High (can be cleared)❌ Low (persists in memory)
Performanceβœ… Fast⚠️ Slightly slower
  • Once created, a String cannot be changed.
  • If you store a password as a String, it stays in memory until garbage collected, which you can’t control directly.
  • Even if you set the reference to null, the actual string data remains in memory.
  • Java stores String literals in a common memory pool.
  • Passwords stored as String may persist longer than needed.
  • Tools like heap dump analyzers or memory scanners could potentially recover passwords from memory.
  • Multiple references to the same string share the same memory location.
  • Heap dumps may contain password strings
  • Application logs might accidentally log password strings
  • Debug tools can inspect string contents in memory
  • JVM crash dumps preserve string data
  • You can manually overwrite the contents of the array after use:
Arrays.fill(password, '0'); // Overwrites each character
  • You decide when to clear the password from memory.
  • Can clear immediately after authentication.
  • No dependency on garbage collection.
  • Character arrays are not interned.
  • Each array is a separate memory location.
  • No risk of sharing memory with other parts of the application.
import java.util.Arrays;
import java.util.Scanner;
public class SecurePasswordExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter password: ");
char[] password = scanner.nextLine().toCharArray();
try {
// Use password for authentication
if (authenticate(password)) {
System.out.println("Authentication successful!");
} else {
System.out.println("Authentication failed!");
}
} finally {
// CRITICAL: Clear password from memory immediately
clearPassword(password);
scanner.close();
}
}
private static boolean authenticate(char[] password) {
// Simulate authentication
String storedHash = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"; // "password"
String inputHash = hashPassword(password);
return storedHash.equals(inputHash);
}
private static String hashPassword(char[] password) {
// In real applications, use proper hashing like BCrypt, PBKDF2, or Argon2
// This is just a simple example
return "hashed_" + new String(password);
}
private static void clearPassword(char[] password) {
if (password != null) {
// Overwrite with zeros
Arrays.fill(password, '\0');
System.out.println("Password cleared from memory.");
}
}
}