Validação de senhas em java

Quantas senhas para acessos online você possui? Suas senhas são seguras? Com a popularidade da internet, e principalmente dos serviços on-line, criar senhas para contas “na nuvem” tem se tornando cada vez mais comuns na vida das pessoas. Mas muitos dos internautas não se preocupam com o quão seguras são suas senhas. Segundo pesquisa realizada pela empresa splashdata, que utiliza como parâmetro listas de contas roubadas por hackers e publicadas na rede, a senha mais popular é a sequência de números “123456” seguida da palavra “password”. Para evitar esse tipo de “distração” na criação de contas, muitas aplicações adotam políticas de senha que não só definem o tamanho mínimo, mas também obrigam a composicão da senha, com letras, números e caracteres especiais. Nesse post vou mostrar como criar regras de composição de senhas de forma simples utilizando java e a API Passay.

1 – O primeiro passo é incluir o Passay na lista de dependências do maven. Inclua o seguinte trecho de código entre as tags <dependencies> e </dependencies> no pom.xml do seu projeto.

<dependency>
	<groupId>org.passay</groupId>
	<artifactId>passay</artifactId>
	<version>1.0</version>
</dependency>

Se você não usa o maven, inclua o jar do Passay na pasta de libraries do seu projeto. O jar pode ser encontrado aqui.

2 – Crie uma classe que será responsável por verificar a senha. Crie valores constantes para definir os valores de cada regra. Por exemplo:

private static final int TAMANHO_MINIMO = 4;
private static final int TAMANHO_MAXIMO = 14;
private static final int QUANTIDADE_DIGITOS = 2;
private static final int QUANTIDADE_LETRAS = 2;

Esses valores podem também ser gravados num banco de dados e recuperados em tempo de execução.

3 – Crie um método para checar se a nova senha é válida, conforme exemplo:

private List<String> checkPasswordRules(String senha) throws Exception{
	if (StringUtils.isBlank(senha)){
		throw new Exception("Senha deve ser informada");
	}
	
	// regra de tamanho mínimo/máximo
	LengthRule lr = new LengthRule(TAMANHO_MINIMO, TAMANHO_MAXIMO);
	
	// regra de espaços não permitidos
	WhitespaceRule wr = new WhitespaceRule();
	
	// regra de caracter alfabético obrigatório
	AlphabeticalCharacterRule  ac = new AlphabeticalCharacterRule (QUANTIDADE_LETRAS); 
	
	// regra de dígitos obrigatórios
	DigitCharacterRule dc = new DigitCharacterRule(QUANTIDADE_DIGITOS);
	
	// regra de caracteres especiais obrigatórios
	SpecialCharacterRule  nac = new SpecialCharacterRule ();
	
	// regra de caracter maiúsculo obrigatório
	UppercaseCharacterRule uc = new UppercaseCharacterRule();
	
	List<Rule> ruleList = new ArrayList<Rule>();
	ruleList.add(lr);
	ruleList.add(wr);
	ruleList.add(ac);
	ruleList.add(dc);
	ruleList.add(nac);
	ruleList.add(uc);
	
	Properties props = new Properties();
	props.load(new FileInputStream("./src/main/resources/messages.properties"));
	MessageResolver resolver = new PropertiesMessageResolver(props);
	
	PasswordValidator validator = new PasswordValidator(resolver, ruleList);
	PasswordData passwordData = new PasswordData(new String(senha));

	RuleResult result = validator.validate(passwordData);
	if (!result.isValid()) {
	  return validator.getMessages(result);
	}
	return null;
}

Nesse exemplo, incluí as regras de tamanho mínimo e tamanho máximo, letras, números, maiúsculos e caracteres especiais obrigatórios. As classes xxRule, como por exemplo, LenghtRule ou AlphabeticalRule são classes pré definidas da ferramenta.

Na linha 52, todas as regras são incluidas em uma lista e passadas para o validador, da linha 64.

Na linha 64 forneço também o arquivo .properties onde estão as traduções para as mensagens. Esse parâmetro é opcional, mas se não for informado, as mensagens de erro estarão em inglês.

Na linha 39 estou aplicando as regras de senha para a senha informada.

Se a senha não for válida, o método isValid() da classe RuleResult (linha 40) retorna false. As mensagens podem ser obtidas através do método getMessages() (linha 41)

4 – Crie um arquivo messages.properties para definir as mensagens de erro que serão exibidas para cada regra não atendida, conforme exemplo:

ILLEGAL_WHITESPACE=Senha não pode conter espaços em branco.
INSUFFICIENT_UPPERCASE=Senha deve conter pelo menos %1$s caracter(es) maiúsculo(s).
INSUFFICIENT_LOWERCASE=Senha deve conter pelo menos %1$s caracter(es) minúsculo(s).
INSUFFICIENT_ALPHABETICAL=Senha deve conter pelo menos %1$s caracter(es) alfabético(s).
INSUFFICIENT_DIGIT=Senha deve conter pelo menos %1$s dígito(s).
INSUFFICIENT_SPECIAL=Senha deve ter pelo menos %1$s caracter(es) especiais.
TOO_LONG=Senha não deve conter mais de %2$s caracter(es).
TOO_SHORT=Senha deve ter no mínimo %1$s caracter(es).

os valores %1$ e %2$ são parâmetros que a API utiliza para montagem dos textos.

5 – Agora só criar um método para testar.

public static void main(String[] args) throws Exception {
		PassayUtil passay = new PassayUtil();
		
		// Chamando o método para testar a senha 123
		List<String> messages = passay.checkPasswordRules("123");
		// se retornou mensagens, entao nao passou nas regras..
		if (messages != null){
			System.out.println("Senha inválida. Mensagens:");
			for (String msg : messages){
				System.out.println("-"+msg);
			}
		}else{
			System.out.println("Senha válida");
		}
	}

Rodando o teste com a senha “123” as seguintes mensagens são exibidas:

Senha inválida. Mensagens:
-Senha deve ter no mínimo 4 caracter(es).
-Senha deve conter pelo menos 2 caracter(es) alfabético(s).
-Senha deve ter pelo menos 1 caracter(es) especiais.
-Senha deve conter pelo menos 1 caracter(es) maiúsculo(s).

 

Além das funcionalidades apresentadas nesse post, a API Passay oferece também facilidades para criação de novas regras, geração de senhas aleatórias, histórico de senhas antigas e até um dicionário com palavras que não podem ser usadas para montagem da senha. Apesar de ser relativamente fácil fazer as validações básicas de senha na mão, utilizar a API torna a tarefa mais fácil e mais confiável, além de possibilitar uma maior flexibilidade para possíveis novas regras.

Referências
http://www.passay.org/reference/
http://gizmodo.com/the-25-most-popular-passwords-of-2014-were-all-doomed-1680596951

Por MARCIA TANIMOTO

Formada em Informática - UEM/Maringá. Analista de Sistemas, apaixonada pela profissão, curiosa e MATERANA de coração.

Postado em: 24 de junho de 2015

Confira outros artigos do nosso blog

REST não é JSON

21 de agosto de 2017

Bruno Sofiato

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

JavaScript 6: diferença entre var, let e const

09 de maio de 2017

Otávio Felipe do Prado

Deixe seu comentário