This question is a follow up on the question here:
Why is char[] preferred over String for passwords?
That question is great for understanding why it is good to use a char[] instead of a String; however, it doesn't explain how to perform password validation on a char[] in a secure manner. That is what I would like to know about here.
Put simply, I need to check to see if a password meets the following requirements:
Now I understand how I can use regular expressions to perform the validation... these answers show how to do that:
As far as I know, regular expression checks involve working with strings. It doesn't seem secure to use them because strings are immutable, and thus they cannot be cleared immediately after using them. A char[], on the other hand, can be cleared.
I could iterate through each character, but then I would have to create each set that I want to test. Ideally, it would be useful to be able to take advantage of regular expressions.
In Java, I can do regular expressions check via the following methods.
String.matches(String regex)
Or
Pattern pattern = Pattern.compile(String regex);
pattern.matcher(CharSequence testString).matches();
As you can see, both methods do not support working directly with a char[].
Since Strings are immutable there is no way the contents of Strings can be changed because any change will produce a new String, while if you use a char[] you can still set all the elements as blank or zero. So storing a password in a character array clearly mitigates the security risk of stealing a password.
I would try to avoid a complicated regex, I would suggest something like -
boolean validatePassword(char[] password, int n, int m) {
if (password == null || password.length < n || password.length > m) {
return false;
}
boolean upper = false;
boolean lower = false;
boolean digit = false;
boolean symbol = false;
for (char ch : password) {
if (Character.isUpperCase(ch)) {
upper = true;
} else if (Character.isLowerCase(ch)) {
lower = true;
} else if (Character.isDigit(ch)) {
digit = true;
} else { // or some symbol test.
symbol = true;
}
// This short-circuits the rest of the loop when all criteria are true.
if (upper && lower && digit && symbol) {
return true;
}
}
return upper && lower && digit && symbol;
}
Just iterate through char[]
to do basic password acceptance validation
You can use CharBuffer.wrap(char[])
to access the char array as a CharSequence
.
Pattern.matches(regex, CharBuffer.wrap(myCharArray))
Java's regex implementation does not require String
objects - you are expected to pass a CharSequence
. If you would rather not create a String
from a char[]
array, you could wrap an array in your own implementation of the CharSequence
interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With