Passwords and Social Security Number (SSN) are sensitive and confidential information that should be protected from unauthorized access or exposure. However, many developers make the mistake of storing passwords as plain text in String objects, which can pose serious security risks. In this post, we will explain why character array is preferred over String for storing highly sensitive information in Java.

Why we should not use a String to store passwords?

Strings are immutable in Java, which means that once they are created, they cannot be modified or deleted. This has some advantages, such as improving performance and memory efficiency, but it also has some disadvantages, especially when it comes to storing passwords.

One of the main disadvantages of using String for passwords is that they are stored in the String pool, which is a special area of the heap memory where Java stores all the String literals. The String pool is used to reuse the same String objects and reduce memory consumption. However, this also means that the passwords stored as Strings will remain in the memory until the garbage collector clears them, which can take a long time.

This creates a security vulnerability, as anyone who has access to the memory dump can find the passwords in clear text and use them for malicious purposes. For example, an attacker can use a tool like Java Memory Analyzer to analyze the heap dump and extract the passwords from the String pool.

 
Another disadvantage of using String for passwords is that there’s always a risk of accidentally printing the password to the console or application logs. For example, if we print or log the password as a String, it will be displayed as plain text. This can expose the password to anyone who can read the output or access the log file.

Download  Run Code

Why a character array is preferred over a string?

We should always use a character array to collect and store sensitive information. Unlike String, character array is mutable, which means that it can be modified or deleted. They are not stored in the String pool, but in a separate area of the heap memory where Java stores all the arrays. This means that the passwords stored as character arrays will not be reused or shared by other objects, and they will be cleared from the memory as soon as the array object is dereferenced or set to null.

This reduces the security risk of exposing the passwords to memory dump analysis, as they will not be present in the memory for a long time. Moreover, to avoid passwords being displayed in plain text in the thread dump/heap analyzer, we should explicitly wipe out data containing sensitive information immediately after use, instead of waiting for the garbage collection to kick in. For example:

Download  Run Code

 
Another advantage of using character array for passwords is that they are not easily accessible or visible to anyone who can see the source code or the logs. The toString() method of a character array does not print the contents of the array; its memory address will get printed instead like [C@3941a79c. This makes it harder for anyone to read or guess the password from the output or the log file.

Download  Run Code

 
Even this is not secure as the password can be still logged in several other ways. Therefore, a character array is less vulnerable than a String, even though it only reduces the attack window for the successful hack and doesn’t eliminate the risk.

Download  Run Code

That’s all about why character array is preferred over String for storing passwords. We can conclude that a character array is more secure than a String, even though it also can be exploited. To avoid any leaks, we should always encrypt a password rather than storing it in plain text and clear it from the heap as soon as the user is authenticated.

 
Also See:

Difference between String and Character array in Java