Proteger uma palavra-passe na base de dados com encriptação

Ultimamente tem-se falado muito nos ataques a bases de dados e na divulgação de dados pessoais. Nenhuma aplicação é imune, mas será que pelo menos dificultam a vida aos hackers quando ficam com a vossa base de dados?

Segurança

Tem-me passado muito código pelas mãos que está mal executado, mas o que realmente me faz confusão são as palavra-passe em texto (plain-text) guardadas numa base de dados.

É engraçado abrir o phpMyAdmin e ver que a palavra-passe do admin é password123 em vez de 482c811da5d5b4bc6d497ffa98491e38 por exemplo.

E nós como utilizadores conseguimos saber se uma palavra-passe está a ser guardada localmente, basta fazer a recuperação de password e consultar se o texto devolvido é o mesmo que colocamos anteriormente.

Encriptação

Quando guardamos uma palavra-passe numa base de dados nunca guardamos a palavra-passe em si mas uma hash que corresponde à palavra-passe. Mas depois não sei a pass ou tenho que a decriptar pensam vocês. Nada disto é necessário.

Quando um utilizador se autentica no vosso website o que fazemos é encriptar o texto que o utilizador colocou e comparar a hash resultante com a hash que temos na nossa base de dados. Devemos usar uma hash que apenas permita a encriptação como o SHA512 ou o Whirlpool. O MD5 e o SHA1 não são aconselhados por serem rápidos a criar a hash, um computador pode resolver uma password com 6 caracteres numa questão de horas. Ao contrário de tudo o resto, ao criar uma hash quanto mais lento, melhor!

Desta forma se o vosso website for atacado e base de dados for obtida por um hacker ele apenas vai ter acesso a um monte de hash’s, mas isso não quer dizer que o nosso conteúdo esteja protegido.

Rainbow Tables e Salt

Existem listas, chamadas Rainbow Tables, de hash’s encriptadas que permitem efectuar uma pesquisa pela hash e obter o valor a que corresponde. Se numa Rainbow Table procurarmos por 482c811da5d5b4bc6d497ffa98491e38 possivelmente vamos obter o resultado password123.

Estas tabelas usam principalmente palavras comuns, disponíveis no dicionário e se não obrigamos os nossos utilizadores a colocar palavras-passe complexas estamos em risco. A maneira de resolver esta situação é aplicar Salt (Sal, literalmente).

Os utilizadores são preguiçosos e não ligam a segurança. Uma password para eles deve ser simples. É má prática, mas se não fazemos nada contra isso podemos criar mecanismos de protecção. Um deles, na encriptação de palavras-passe é a utilização de Salt.

Vamos supor que o utilizador tem password123 definida mas em vez de encriptarmos este valor adicionamos Salt ao inicio da password e encriptamos a password como fe#S7password123. A nossa hash vai ser totalmente diferente e uma Rainbow Table muito dificilmente terá este valor. O nosso Salt é então fe#S7 e devemos usar o mesmo quando o utilizador fizer a sua autenticação.

Espero que não seja necessário dizer isto, mas o Salt deve sempre ser guardado server-side, não coloquem o Salt num input de um formulário. Mas de qualquer forma aqui fica um exemplo:

1
2
3
4
5
<?php
  define( 'SALT', 'fe#S7' );
  $password = 'password123';
  $hash = hash( 'sha512', SALT . $password );
?>

O Salt está pré-definido no servidor, a variável $password é fornecida pelo utilizador e no final encriptamos ambos os valores para obter uma hash com Salt.

Isto já é consideravelmente seguro, mas podemos fazer melhor. No meu exemplo estou a usar um Salt pequeno, este deve ser maior. Podemos também aplicar mais Salt no meio de uma password ou no final para a tornar mais complexa. Também podemos alterar a hash retornada e aplicar também Salt nesse valor. Mas esta opção já é complexa e necessita de valores aleatórios para cada password, caso contrário ao olharmos para 5 hash’s facilmente verificamos qual é o Salt utilizado.

Encriptação online de palavras-chave

Fujam a sete pés de sites que criam hash’s online. Nem todos são maliciosos mas muitos usam os valores colocados pelos utilizadores para popular Rainbow Tables, criando um precedente para que a vossa palavra-passe seja insegura no caso de um ataque a um site onde estejam registados e seja usada a encriptação sem Salt.

Se querem testar hash’s devem sempre criar o vosso script e não ficar dependente de serviços de terceiros pois nunca sabemos o que é efectuado com os nossos dados.

Programar com segurança em mente

Espero que esta entrada no blog vos faça repensar como programam e guardam os dados dos utilizadores em base de dados.

Se programam mal e são atacados o problema é vosso, mas se dados de terceiros são perdidos por falta de atenção a estes detalhes então já estamos a por em causa a segurança dos outros.

Nota:
Foi usado como exemplo uma hash gerada em MD5 (482c811da5d5b4bc6d497ffa98491e38), apesar de advertir contra o uso deste algoritmo para encriptação de passwords. Este foi usado por gerar uma hash mais pequena que SHA512 (32 contra 128 caracteres), tornando a leitura do artigo mais amigável.
 
Copyright © 1985 - 2017 Eduardo Maio. Alguns direitos reservados.
eduardomaio.net - Às vezes mais valia ser Agricultor do que Programador
Ao navegar no blog eduardomaio.net está a concordar com os termos legais e de privacidade.