When developing secure applications, a common question arises: why is char preferred over string for passwords? Storing passwords in plain text is a significant security risk, but the choice of data structure in memory is equally important.
In this guide, we will examine the technical reasons why is char preferred over string for passwords in Java and C#, focusing on memory management, the String Constant Pool, and heap dump vulnerability protection.
The Security Risk of Strings: Immutability & The String Pool
To understand why is char preferred over string for passwords, we must look at how String objects are managed in memory by virtual machines like the JVM.
In Java, String objects are immutable. This means once a String is created, it cannot be modified or cleared from memory. Furthermore, the JVM optimizes memory by placing String literals in the String Constant Pool. Even if you assign a password String to null, the original value remains in memory until the Garbage Collector decides to sweep it. Because garbage collection is non-deterministic, a password could remain in raw memory for hours, exposing it to memory attacks.
Why Character Arrays (char[]) Are Secure
Unlike Strings, character arrays (char[]) are mutable. This gives the developer direct control over the memory lifecycle of sensitive information. As soon as the password is hashed or validated, you can explicitly overwrite the contents of the array with dummy characters. This ensures the plain-text password is wiped out instantly and is no longer retrievable from a heap dump.
Java Code Example: String vs. char[] Password Handling
Below is a comparative example showing how a String exposes password data in memory, while a char[] allows you to immediately clean it up using java.util.Arrays:
import java.util.Arrays;
public class PasswordSecurityExample {
public static void main(String[] args) {
// VULNERABLE: Password stored as String (cannot be wiped)
String insecurePassword = "SecretPassword123";
System.out.println("Processing insecure String password...");
// insecurePassword remains in the memory heap until GC runs
insecurePassword = null;
// SECURE: Password stored as char[] (can be cleared immediately)
char[] securePassword = new char[]{'S', 'e', 'c', 'r', 'e', 't', '1', '2', '3'};
System.out.println("Processing secure char[] password...");
// Overwrite/wipe the password from memory immediately after use
Arrays.fill(securePassword, '0');
// At this point, securePassword only contains {'0','0','0','0','0','0','0','0','0'}
System.out.println("Password has been wiped from memory.");
}
}Comparing String vs. char[] for Passwords
Here is a direct architectural comparison between the two approaches:
| Security Metric | String Object | Character Array (char[]) |
|---|---|---|
| Mutability | Immutable (cannot be changed) | Mutable (can be modified in-place) |
| Memory Cleanup | Relies on non-deterministic Garbage Collection | Explicitly cleared immediately using Arrays.fill() |
| String Pool Usage | Yes (cached in String Pool) | No (does not cache in pool) |
| Vulnerability to Heap Dumps | High (password stays in plain text) | Low (password wiped out after use) |
Vulnerability to Heap Dumps and Memory Inspection
If an attacker gains unauthorized access to a running application server, they can capture a heap dump (a snapshot of the application’s memory). Since Strings are stored as plain text in the heap, the password will be clearly visible. By using char[] and clearing it right after hashing, you reduce the time window of this vulnerability to milliseconds.
C# / .NET Equivalent: SecureString
In the .NET framework, C# developers face the same string immutability risks. To address this, Microsoft introduced the SecureString class. A SecureString encrypts the text value in memory using DPAPI (Data Protection API) and implements the IDisposable interface, ensuring that the decrypted memory is released and zeroed out as soon as the object is disposed.
Summary of Security Best Practices
- Wipe Immediately: Always use
Arrays.fill()to wipe the character array as soon as you have verified it or converted it to a hash. - Avoid Logging: Never print passwords to application logs or console outputs.
- Hashing is Mandatory: Never store raw passwords in databases. Always hash passwords using secure hashing algorithms (like Argon2 or bcrypt) before storing. For a breakdown on credit card data threats, check out our guide on Credit Card Security Attacks.
Leave a comment