Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I perform validation on a secure password. Regular expressions on a char[]?

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:

  • Contains at least one uppercase letter
  • Contains at least one lowercase letter
  • Contains at least one digit
  • Contains at least one symbol
  • Is at least n characters, but no more than m

Now I understand how I can use regular expressions to perform the validation... these answers show how to do that:

  • Regexp Java for password validation
  • Password must be 8 characters including 1 uppercase letter, 1 special character, alphanumeric characters

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.

So, how can I perform validation on a password which is stored in a char[], and not a string?

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[].

like image 676
Nicholas Miller Avatar asked Jul 24 '14 02:07

Nicholas Miller


People also ask

Why is char [] preferred over string for passwords in Java?

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.


4 Answers

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;
}
like image 96
Elliott Frisch Avatar answered Oct 06 '22 00:10

Elliott Frisch


Just iterate through char[] to do basic password acceptance validation

like image 25
jmj Avatar answered Oct 06 '22 00:10

jmj


You can use CharBuffer.wrap(char[]) to access the char array as a CharSequence.

Pattern.matches(regex, CharBuffer.wrap(myCharArray))
like image 39
holmis83 Avatar answered Oct 06 '22 00:10

holmis83


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.

like image 28
Sergey Kalinichenko Avatar answered Oct 06 '22 00:10

Sergey Kalinichenko