Neste artigo vou mostrar uma forma segura de autenticar usuários em sistemas de bancos de dados. No artigo anterior, com créditos à Rodolfo Barros Chiaramonte e Edward David Monteiro, da Fundação de Ensino Eurípedes Soares da Rocha, mostrei detalhes do algoritmo de criptografia RSA, que ajuda a manter seguras as movimentações financeiras em seu banco, dentre milhares de outras coisas. Neste artigo, mostrarei na prática um mecanismo para evitar definitivamente
que as senhas de usuários em sistemas de banco de dados sejam descobertas.
Para acompanhar este artigo, será necessário baixar os fontes
da unit de criptografia: clique
aqui
Existe também um pequeno programa gerador de hash com os fontes e o código
do exemplo usando Interbase 6.0. clique
aqui
Muitos desenvolvedores, ao criarem sistemas em que um usuário deve fornecer
nome e senha antes de abrirem a tela principal, não se preocupam muito
em como a senha é armazenada. Já encontrei sistemas em que uma
tabela "USUARIOS" era alimentada com dois campos "NOME"
e "SENHA". E a senha ainda era em texto legível.
Um programador deve sempre ter em mente que seu banco de dados está
vulnerável e exposto. Uma observação óbvia deve
estar sendo feita: - Ora, se uma pessoa teve acesso ao banco de dados e conseguiu
descobrir a senha, ela deve ter tido acesso às informações
também, logo a senha não é mais útil. Muitas vezes
descobrir a senha é o objetivo, não para entrar no banco de dados
e roubar informações, mas para se fazer passar por outra pessoa
e adulterar a informação.
Mecanismos de banco de dados como Access e Paradox podem ter as senhas de seus
arquivos quebradas com ajuda de programas específicos, enquanto que contra
bancos de dados mais robustos com MS-SQL e Interbase, basta um aplicativo de
leitura de tráfego em rede para descobrir as senhas dos usuários.
Mas saiba que existem meios que protegem as senhas com maior eficácia.
Um deles é o RSA, o outro, vou mostrar agora.
Hash de MD5.
Um hash é uma síntese numérica de um texto qualquer, falando
bem resumidamente. Na teoria, não existem dois hashes iguais para textos
diferentes. Até mesmo a diferença mais sutil entre os textos produzem
hashes completamente diferentes. Entre os algoritmos mais usados estão
o SHA1 e o MD5. Um hash é produzido quando se deseja uma "assinatura
digital" de um texto ou uma representação numérica
resumida. Esta síntese ou resumo do texto é largamente usada quando
alguém quer assegurar que o texto a ser enviado chegue sem mudanças
ao seu destinatário, ou se houver mudança no caminho, que ela
seja prontamente acusada.
Por exemplo:
Maria envia uma frase para João:
"Sairemos hoje às 10:00".
e em seguida envia o hash da mensagem:
DE1704ED216DEA45375857781230A2F6.
José consegue interceptar a mensagem e a altera para:
"Sairemos hoje às 11:00".
A modificação não foi muito significativa do ponto de
vista gramatical, mas seu hash mudou para:
6A88207D6D66B9FAB923B6DF51D7923C.
Completamente diferente!
Se João recriar o hash da mensagem e comparar com o que Maria enviou,
verá que houve uma mudança. Note que o MD5 não impede a
modificação, mas assegura uma maneira de validar a mensagem. Claro
que o hash não poderá seguir junto com o texto, ou se for, deverá
ser de forma que não possa ser modificado (explicarei como quando falar
sobre Assinaturas Digitais).
Mas nossa aplicação para o MD5 não é esta. Nosso
interesse reside no fato de que um hash de MD5 não pode ser traduzido
para a mensagem original, ou seja, não é possível descobrir,
a partir de um hash, qual foi o texto que o gerou. Isto se torna de vital importância
para nós, que não temos segurança adequada nos mecanismos
de bancos de dados.
Após baixar a unit de criptografia
, crie um projeto novo e adicione U_Cipher no "Uses" do Form.
Crie uma tabela chamada "USUARIOS" em seu banco de dados favorito.
Eu usei o Interbase no exemplo.
Crie dois campos: "NOME" e "SENHA".
Agora, crie uma inclusão de usuário na tabela "USUARIOS",
solicitando nome e senha, mas antes de gravar, faça:
Senha := MD5Hash(Senha);
Isso vai gerar um hash MD5 da senha antes de armazená-la no banco de
dados.
Qual é a vantagem? Se alguém tiver acesso ao banco de dados, jamais
descobrirá a senha do usuário, não podendo entrar no sistema
com as suas credenciais. Na verdade, a senha do usuário não fica
em lugar algum, somente sua síntese única (hash).
Mas como verificar se a senha é correta se ela não fica no banco
de dados?
Ao solicitar o par Nome/Senha como de costume, crie um hash com a senha fornecida
pelo usuário e compare com o existente no banco de dados:
Password := MD5Hash(Password);
If IBTable1.Locate('NOME',User,[]) then
begin
If Password = IBTable1.FieldByName('SENHA').AsString then
ShowMessage('Senha ok!') else ShowMessage('Senha errada.');
end;
Se forem iguais, certamente a senha é a mesma.
Note que o que foi apresentado não se aplica quando se está utilizando
o mecanismo nativo de usuários do Banco de Dados (como quase todos os
SQL Servers possuem).
Não é um conceito complicado, nem difícil de implementar,
mas é de extrema utilidade.
Em artigo futuro, mostrarei a forma "paranóica" de implementar
segurança nos sistemas, usando o RSA.
Depois, mostrarei como criptografar a informação no banco de dados,
tornando seu sistema comprovadamente à prova de invasão.
Observação: Carlos Magno Oliveira de Abreu.
icemagno@hotmail.com
http://www.magnoabreu.kit.net/
|