Passay - The password generation and validation library
Tags: java, passwords, library, programming
Published: 2020-10-06 06:58:12

Applications and websites that allow users to sign-up mostly have restrictions of password like

* Passwords should be 8 characters or more
* Passwords must contain alphabets, numbers and special characters
* Passwords cannot be any of the previous 3 or 5 passwords
* Passwords cannot be easily guessed
* and so on

Implementing these is not trivial in an application and [Passay](http://www.passay.org/) provides the solutions to applications that want to implementation password validation and generation applying the aforesaid like restrictions.

Password generation and validation requires a certain set of rules to be defined. Rules can be broadly categorized into

* Positive rules, that requires a password to match a defined set of rules
* Negative rules, are those that reject a password if it matches those rules

In order to implement the positive and negative rule requirements, the Passay library provided 3 components

* The `Rule` interface - that helps define different Rule types that is used to validate if a password meets the set policy
* `PasswordValidator` - A validator class that validates a given password against a rule set
* `PasswordGenerator` - A password generation class that generates password matching a rule set

Passay already provides a bunch of classes for both the positive and negative rules sets that include

* `AllowedCharacterRule`, `CharacterRule`, `LengthRule` and a few more for positive rules
* Dictionary rules, History rules, `RepeatCharactersRule`, `UsernameRule` and much more on the negative rules

However, we can define our own rules by defining a class that implements the `Rule` interface.

Now let's see Passay in action. In the first code snippet, we define a set of rules that the password provided should satisfy, they are

* Password should be 8, 12 characters long
* Have at least one uppercase and one lowercase alphabet
* Have at least one digit and one special character
* It cannot have a sequence either in the Alphabets or in the Numbers like abcdefg or 234567 and so on.
* It cannot have repeating characters of 4 or more like 88888 or ggggg
* It cannot have a whitespace

Here is the code snippet

```
PasswordValidator validator = new PasswordValidator(
	// length between 8 and 16 characters
	new LengthRule(8, 12),

	// at least one upper-case character
	new CharacterRule(EnglishCharacterData.UpperCase, 1),

	// at least one lower-case character
	new CharacterRule(EnglishCharacterData.LowerCase, 1),

	// at least one digit character
	new CharacterRule(EnglishCharacterData.Digit, 1),

	// at least one symbol (special character)
	new CharacterRule(EnglishCharacterData.Special, 1),

	// define some illegal sequences that will fail when >= 5 chars long
	// alphabetical is of the form 'abcde', numerical is '34567'
	// the false parameter indicates that wrapped sequences are allowed; e.g.
	// 'xyzabc'
	new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 5, false),
	new IllegalSequenceRule(EnglishSequenceData.Numerical, 5, false),
	new RepeatCharactersRule(4),

	// no whitespace
	new WhitespaceRule());

	final char[] password = System.console().readPassword("Password: ");
	RuleResult result = validator.validate(new PasswordData(new String(password)));
	if (result.isValid())
	{
		System.out.println("Password is valid");
	}
	else
	{
		System.out.println("Invalid password:");
		for (String msg : validator.getMessages(result))
		{
			System.out.println(msg);
		}
	}
```
The rules should be self-explanatory. When the code is run, it asks for a password, if we provide a password say 88888, the following would be the output

```
Password: <88888>
Invalid password:
Password must be 8 or more characters in length.
Password must contain 1 or more uppercase characters.
Password must contain 1 or more lowercase characters.
Password must contain 1 or more special characters.
Password contains 1 sequences of 4 or more repeated characters, but only 1 allowed: [88888].
```

As we can clearly see, Passay ensures that all the rules are met before accepting the password

The next part to this is the password generation feature that Passay provides. Let's look at the code snippet. The additional catch to that is the we are validating the password generated by Passay using its own validator to check if the password generated adheres to the rules set in the generation.

```
PasswordGenerator generator = new PasswordGenerator();

// Generated password is 12 characters long, which complies with policy
String passwd = generator.generatePassword(12, rules);
System.out.println("Generated Password:" + passwd);

PasswordValidator validator2 = new PasswordValidator(
		// length between 8 and 16 characters
		new LengthRule(12),

		// at least one upper-case character
		new CharacterRule(EnglishCharacterData.UpperCase, 1),

		// at least one lower-case character
		new CharacterRule(EnglishCharacterData.LowerCase, 1),

		// at least one digit character
		new CharacterRule(EnglishCharacterData.Digit, 4));
RuleResult res = validator2.validate(new PasswordData(passwd));
if (res.isValid())
{
	System.out.println("Valid");
}
else
{
	System.out.println("Invalid");
}
```

Running the code would produce an output similar to this

```
Generated Password:Rb4Xdj1KO570
Valid
```
Passay definitely makes life easy for developers who want to validate/generate passwords. In addition to the examples above, Passay provides much more complex scenarios like historical passwords where password should be any of the previous 3 passwords; satisfy m of n rules defined and so on. In addition the rule set is extensible by implementing the Rule interface for additional rules.

Head on to [www.passay.org](http://www.passay.org/) for more details.

Happy coding!

Image Credit: [Pixabay](https://pixabay.com/users/janbaby-3005373/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2168233)