A string is an object in Java that represents a sequence of character values. Strings are immutable, which means once they are created, we cannot change their value. It is recommended to use the char[] array for storing passwords over strings in Java because of following reasons:
1. Strings are immutable
In Java, the memory is divided into two parts: HEAP and STACK. If we create any string, it is going to be stored inside the string pool constant (SCP) in the heap memory, and its corresponding string variable is going to be stored in the stack memory. For example, if we create a string as below:
String pwd = "paulsofts";
The reference variable pwd is going to be stored in the stack, and the string value paulsofts is going to be stored in the heap memory.
As we have stored our password as plain text in a string, if we want to update our password from paulsofts to paulsofts@123, the JVM is going to create a new string value inside the string pool constant, and the reference variable is going to break the reference to the previous string value and refer to the new string value.
In the above picture, we can see that our reference variable is now pointing to the new password. i.e, paulsofts@123 But still, the old password will remain in the string pool as a constant, and this is the reason why strings are immutable in Java. The old password will remain in memory until garbage collectors clear it. But in the case of a character array, it will be overridden with the new value, and the old value will not be available anywhere in the memory even before the garbage collection.
2. Password theft
As we have our old password still present in the string pool constant. Anyone who has a memory dump (or heap dump) can easily trace our password. That’s why it is recommended to use an encrypted password instead of plain text. For more details, please refer to the official document, IBM SDK, Java Technology Edition. On the other hand, storing passwords in a character array will reduce the risk of password theft.
3. Logs
As developers, we use logs to monitor and check the workflow of our application programs. Sometimes we simply print the logs, which may not be removed before moving the code to production, and the console prints statements that may be present in the server logs. In the below example, we can see how server logs can contain sensitive information or passwords stored in strings.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class PasswordSecurity {
//logger instance for our PasswordSecurity class
public static Logger LOGGER = LogManager.getLogger(PasswordSecurity.class);
public static void main(String[] args) {
//string
String pwd = "paulsofts";
LOGGER.info("String password: " + pwd);
//character array
char[] arr = new char[] {'p', 'a', 'u', 'l', 's', 'o', 'f', 't', 's'};
LOGGER.info("Charcter array password: " + arr);
}
}
The output for the above program is shown below. As we can see, the password stored in the string field is displayed in the logs, while the one stored in the character array it’s address gets printed.
While using a character array to store passwords, we can use the Arrays.fill(char[] c, char val) method to hide our passwords with some special characters or values.
import java.util.Arrays;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class PasswordSecurity {
//logger instance for our PasswordSecurity class
public static Logger LOGGER = LogManager.getLogger(PasswordSecurity.class);
public static void main(String[] args) {
//string
String pwd = "paulsofts";
LOGGER.info("String password: " + pwd);
//character array
char[] arr = new char[] {'p', 'a', 'u', 'l', 's', 'o', 'f', 't', 's'};
LOGGER.info("Charcter array password: " + arr);
//without Arrays.fill()
for(char c : arr) {
System.out.print(c);
}
//for changing the line
System.out.println();
//with Arrays.fill()
Arrays.fill(arr, '*');
for(char c : arr) {
System.out.print(c);
}
}
}
In the above program, we have used the Arrays.fill() method to fill our character array with an asterisk (*).