Não faz muito tempo que foi divulgado aqui que usuários escolhem muito mal as senhas na hora de cadastrar em um sistema. Por isso para proteger nosso sistema devemos proteger ao máximo o usuário também, pois ele estando de certa forma mais seguro você também estará!
Nesse tutorial vamos ver como podemos criar um simples algoritmo para verificar a força da senha do usuário para que possamos validar sua entrada.
Vamos fazer um algoritmo baseado em pontos, ou seja, vamos definir a força da senha de acordo com a pontuação que senha dele obteve. Veja aqui nosso sistema de pontos :
GetPontoPorTamanho -Seis pontos serão atribuídos para cada caractere na senha, até um máximo de sessenta pontos.
GetPontoPorMinusculas – Cinco pontos serão concedidos se a senha inclui uma letra minúscula. Dez pontos serão atribuídos se mais de uma letra minúscula estiver presente.
GetPontoPorMaiusculas – Cinco pontos serão concedidos se a senha incluir uma letra maiúscula. Dez pontos serão atribuídos se mais de uma letra maiúscula estiver presente.
GetPontoPorDigitos – Cinco pontos serão concedidos se a senha incluir um dígito numérico. Dez pontos serão atribuídos se mais de um dígito numérico estiver presente.
GetPontoPorSimbolos – Cinco pontos serão concedidos se a senha incluir qualquer caractere diferente de uma letra ou um dígito. Isto inclui símbolos e espaços em branco. Dez pontos serão concedidos se houver dois ou mais de tais caracteres.
GetPontoPorRepeticao – Se houver caracteres repetidos na senha será atribuido 30 pontos que será subtraida da fórmula do cálculo do total dos pontos;
Simples não é mesmo?
Veja a classe que eu criei :
public class ChecaForcaSenha { public enum ForcaDaSenha { Inaceitavel, Fraca, Aceitavel, Forte, Segura } /* GetPontoPorTamanho -Seis pontos serão atribuídos para cada caractere na senha, até um máximo de sessenta pontos. GetPontoPorMinusculas - Cinco pontos serão concedidos se a senha inclui uma letra minúscula. Dez pontos serão atribuídos se mais de uma letra minúscula estiver presente. GetPontoPorMaiusculas - Cinco pontos serão concedidos se a senha incluir uma letra maiúscula. Dez pontos serão atribuídos se mais de uma letra maiúscula estiver presente. GetPontoPorDigitos - Cinco pontos serão concedidos se a senha incluir um dígito numérico. Dez pontos serão atribuídos se mais de um dígito numérico estiver presente. GetPontoPorSimbolos - Cinco pontos serão concedidos se a senha incluir qualquer caractere diferente de uma letra ou um dígito. Isto inclui símbolos e espaços em branco. Dez pontos serão concedidos se houver dois ou mais de tais caracteres. GetPontoPorRepeticao - Se houver caracteres repetidos na senha será atribuido 30 pontos que será subtraida da fórmula do cálculo do total dos pontos; */ public int geraPontosSenha(string senha) { if (senha == null) return 0; int pontosPorTamanho = GetPontoPorTamanho(senha); int pontosPorMinusculas = GetPontoPorMinusculas(senha); int pontosPorMaiusculas = GetPontoPorMaiusculas(senha); int pontosPorDigitos = GetPontoPorDigitos(senha); int pontosPorSimbolos = GetPontoPorSimbolos(senha); int pontosPorRepeticao = GetPontoPorRepeticao(senha); return pontosPorTamanho + pontosPorMinusculas + pontosPorMaiusculas + pontosPorDigitos + pontosPorSimbolos - pontosPorRepeticao; } private int GetPontoPorTamanho(string senha) { return Math.Min(10, senha.Length) * 7; } private int GetPontoPorMinusculas(string senha) { int rawplacar = senha.Length - Regex.Replace(senha, "[a-z]", "").Length; return Math.Min(2, rawplacar) * 5; } private int GetPontoPorMaiusculas(string senha) { int rawplacar = senha.Length - Regex.Replace(senha, "[A-Z]", "").Length; return Math.Min(2, rawplacar) * 5; } private int GetPontoPorDigitos(string senha) { int rawplacar = senha.Length - Regex.Replace(senha, "[0-9]", "").Length; return Math.Min(2, rawplacar) * 6; } private int GetPontoPorSimbolos(string senha) { int rawplacar = Regex.Replace(senha, "[a-zA-Z0-9]", "").Length; return Math.Min(2, rawplacar) * 5; } private int GetPontoPorRepeticao(string senha) { System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"(\w)*.*\1"); bool repete = regex.IsMatch(senha); if (repete) { return 30; } else { return 0; } } public ForcaDaSenha GetForcaDaSenha(string senha) { int placar = geraPontosSenha(senha); if (placar < 50) return ForcaDaSenha.Inaceitavel; else if (placar < 60) return ForcaDaSenha.Fraca; else if (placar < 80) return ForcaDaSenha.Aceitavel; else if (placar < 100) return ForcaDaSenha.Forte; else return ForcaDaSenha.Segura; } }
Para utilização eu criei um projeto em Windows Forms e adicionei apenas um textbox e 2 label. Criei um evento de text_changed no textbox e o implementei, veja :
private void txtSenha_TextChanged(object sender, EventArgs e) { if (txtSenha.Text != string.Empty) { ChecaForcaSenha verifica = new ChecaForcaSenha(); int placar; ForcaDaSenha forca; placar = verifica.geraPontosSenha(txtSenha.Text); forca = verifica.GetForcaDaSenha(txtSenha.Text); lblPontosSenha.Text = placar.ToString() + " Pontos"; lblForcaSenha.Text = forca.ToString(); } }
Bom, é isso, é claro que poderíamos ter otimizado o algoritmo e aumentado a performance, porém preferi fazer algo simples ( Código Simples.NET 😉 ) ao invés de optar por algo complexo.
o donwload do projeto você pode fazê-lo aqui no meu GitHub
Obrigado pessoal e até a próxima!