Neste artigo vou mostrar uma alternativa para tratar informação sensível como senhas de uma forma mais segura armazenando o hash da senha no registro do sistema. |
A solução usada e mostrada neste artigo armazena o hash da senha no registro do sistema e testa a senha informada comparando seu hash contra e entrada do registro.
Vamos recordar os conceitos sobre Hash e sobre o Registro do sistema.
Hash
Um hash é uma seqüencia de letras ou números geradas por um algorítimo de Hash.
Na criptografia, o hash serve para
garantir a integridade da mensagem, onde o gerador (ou emissor) da
mensagem, submete-a a um algoritmo hash, o qual produzirá um valor hash.
Este valor é enviado junto com a mensagem para o destinatário. O
destinatário fará a verificação da integridade da mensagem aplicando o mesmo
algoritmo na mensagem original e obterá um valor hash que deverá ser igual
ao valor hash gerado na origem.
O algoritmo hash é composto por fórmulas matemáticas complexas, para poder
garantir a irreversibilidade e a unicidade do MD gerado - textos diferentes
não produzem o mesmo MD. A alteração de um simples bit na mensagem gera um
MD completamente diferente e o valor de conferência ("check-sum")
muda se um único bit for alterado, acrescentado ou retirado da mensagem.
Registro
O registro do Windows é um banco de dados central que armazena as definições das configurações e outra informação exigida pelas aplicações. As duas únicas tarefas que você consegue fazer com o registro é ler e escrever nele.
Para poder trabalhar como registro a livraria .NET Framework fornece duas classes - Registy e RegistryKey.
Estas classes estão definidas no namespace - Microsoft.Win32 ; de forma que para que possamos usá-las devemos fazer referência a este namespace.
Podemos definir as chaves do registro na seguinte ordem:
CurrentUser - Armazena informação sobre as preferências do usuário.
LocalMachine - Armazena a configuração da informação para a máquina
local
ClassesRoot - Armazena informação sobre tipos e classes e suas
propriedades.
Users - Armazena informação sobre a configuração padrão do usuário.
PerformanceData - Armazena informação de desempenho para os
componentes de software.
CurrentConfig - Armazena informação sobre hardware.
DynData - Armazena dados dinâmicos.
A classe Registry contém membros que fornecem acesso as chaves do registro. Os membros correspondentes a cada um dos tipos das chaves acima citadas estão descritos abaixo:
ClassesRoot | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_CLASSES_ROOT |
CurrentConfig | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_CURRENT_CONFIG |
CurrentUser | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_CURRENT_USER |
DynData | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_DYN_DATA |
LocalMachine | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_LOCAL_MACHINE. |
PerformanceData | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_PERFORMANCE_DATA |
Users | Retorna um tipo RegistryKey o qual fornece acesso a chave HKEY_USERS |
Vamos usar essas informações para realizar duas tarefas :
Armazenar o usuário e o hash da senha no registro do sistema
Verificar se um usuário e senha informados conferem com os dados armazenados
Recursos usados:
Criando o projeto Windows Forms
Abra o VS 2015 Community e crie um novo projeto (File-> New Project) usando a linguagem VB .NET e o template Windows Forms Application.
No formulário padrão Form1.vb inclua os controles :
2 Panels
4 Labels
4 TextBox - txtUsurio, txtSenha, txtUsurio1, txtSenha1
2 Buttons - btnArmazenar , btnVerificar
Disponha os controles conforme o leiaute da figura abaixo:
Criando a função com os métodos para armazenar e verificar a senha
A seguir vamos criar uma classe no projeto chamada Servicos.cs com o seguinte código :
Imports System.Security.Cryptography
Imports System.Text
Public Class Servicos
Public Sub ArmazenaUsuarioSenha(ByVal nomeUsuario As String, ByVal senhaTexto As String)
Try
' ----- Salva a senha cifrada no registro
Dim hashSenha As String = GetHash(senhaTexto)
My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\SenhaTeste", nomeUsuario, hashSenha)
Catch ex As Exception
Throw ex
End Try
End Sub
Public Function VerificaSenha(ByVal nomeUsuario As String, ByVal senhaTexto As String) As Boolean
Try
' ----- Verifica se o nome do usuário e senha passados conferem no registro
Dim hashSenha As String = GetHash(senhaTexto)
' ----- Retorna qualquer valor armazenado
Dim hashSenhaLido As String =
Convert.ToString(My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\SenhaTeste", nomeUsuario, Nothing))
' ----- Compara as senhas
If (hashSenhaLido = Nothing) Then
' ----- usuário inválido
Return False
ElseIf (hashSenhaLido = hashSenha) Then
' ----- usuário e senha ok
Return True
Else
' ----- Usuario ok, senha inválida
Return False
End If
Catch ex As Exception
Throw ex
End Try
End Function
Public Function GetHash(ByVal texto As String) As String
' ----- Gera o hash e retorna uma string vazia se houver erros
Dim plainBytes As Byte()
Dim hashEngine As MD5CryptoServiceProvider
Dim hashBytes As Byte()
Dim hashTexto As String
Try
' ----- Converte o texto para um array de bytes
plainBytes = Encoding.UTF8.GetBytes(texto)
' ----- Selecione um engine para hash
hashEngine = New MD5CryptoServiceProvider
' ----- Pega o hash do texto em bytes.
hashBytes = hashEngine.ComputeHash(plainBytes)
' ----- Converte o hash de bytes para uma string hexadecimal
hashTexto = Replace(BitConverter.ToString(hashBytes), "-", "")
Return hashTexto
Catch
Return ""
End Try
End Function
End Class
|
Nesta classe criamos os seguintes métodos:
ArmazenaUsuarioSenha - armazena o hash da senha no registro do sistema em HKEY_CURRENT_USER\Software\SenhaTeste;
VerificaSenha - verifica se a senha informada coincide com a armazenada no registro para o usuário informado;
GetHash - Gera o hash para um texto informado usando o MD5CryptoServiceProvider;
Agora basta implementar no formulário do projeto o armazenamento e a verificação da senha.
Implementando o armazenamento e a verificação do hash
No formulário Form1.vb vamos começar criando uma instância da classe Servicos:
Dim servico As New Servicos()
A seguir no evento Click do botão Armazenar no Registro inclua o código a seguir:
Private Sub btnArmazena_Click(sender As Object, e As EventArgs) Handles btnArmazena.Click
If String.IsNullOrWhiteSpace(txtUsuario.Text) Then
MessageBox.Show("Informe o nome do usuário")
Return
End If
If String.IsNullOrWhiteSpace(txtSenha.Text) Then
MessageBox.Show("Informe a senha")
Return
End If
Try
servico.ArmazenaUsuarioSenha(txtUsuario.Text, txtSenha.Text)
MessageBox.Show("Usuário e senha armazenadas com sucesso no Registro")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
|
No evento Click do botão Verificar inclua o código abaixo:
Private Sub btnVerifica_Click(sender As Object, e As EventArgs) Handles btnVerifica.Click
If String.IsNullOrWhiteSpace(txtUsuario1.Text) Then
MessageBox.Show("Informe o nome do usuário")
Return
End If
If String.IsNullOrWhiteSpace(txtSenha1.Text) Then
MessageBox.Show("Informe a senha")
Return
End If
Try
If servico.VerificaSenha(txtUsuario1.Text, txtSenha1.Text) Then
MessageBox.Show("Usuário e Senha informados conferem...")
Else
MessageBox.Show("Usuário e/ou Senha informados NÃO conferem...")
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
|
Executando projeto e armazenando uma senha e depois fazendo a verificação com uma senha incorreta iremos obter:
Pegue o projeto aqui : Hash_Registro.zip (sem as referências)
Pois, assim como o Pai ressuscita os
mortos, e os vivifica, assim também o Filho vivifica aqueles que quer.
E também o Pai a ninguém julga, mas deu ao Filho todo o juízo;
Para que todos honrem o Filho, como honram o Pai. Quem não honra o Filho,
não honra o Pai que o enviou.
João 5:21-23
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Visual Studio - Dica de produtividade - Quick Launch - Macoratti.net
Visual Studio - Dica de produtividade - Nuget - Macoratti.net
VB .NET - O Calculando o CheckSum para um arquivo - Macoratti.net
VB .NET - Trabalhando com o registro do Windows - Macoratti.net
Acessando o Registro do Windows e os arquivos INI - Macoratti.net