Já faz um tempo desde que fiz essa pergunta e estou muito mais familiarizado com a teoria criptográfica agora, então aqui está a abordagem mais moderna:
Raciocínio
- Não use md5. Não use um único ciclo de hashes rápidos da família sha. Hashes rápidos ajudam os invasores, então você não quer isso.
- Use um hash com uso intensivo de recursos, como bcrypt. O Bcrypt é testado ao longo do tempo e pode ser dimensionado para ser à prova de futuro.
- Não se preocupe em rolar seu próprio sal, você pode estragar sua própria segurança ou portabilidade, confie em gen_salt() para gerar seus incríveis sais exclusivos para cada uso por conta própria.
- Em geral, não seja idiota, não tente escrever sua própria criptomoeda, apenas use o que pessoas inteligentes forneceram.
Pacotes de instalação do Debian/Ubuntu
sudo apt-get install postgresql // (of course)
sudo apt-get install postgresql-contrib libpq-dev // (gets bcrypt, crypt() and gen_salt())
sudo apt-get install php5-pgsql // (optional if you're using postgresql with php)
Ative crypt() e bcrypt no postgresql em seu banco de dados
// Create your database first, then:
cd `pg_config --sharedir` // Move to the postgres directory that holds these scripts.
echo "create extension pgcrypto" | psql -d yOuRdATaBaSeNaMe // enable the pgcrypo extension
Use crypt() e gen_salt() em consultas
Compare :pass to hash existente com:
select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)
Crie um hash de :password com um ótimo sal aleatório:
insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)
O hash de bcrypt de dentro do PHP é um pouco preferível
Existem
password_*
funções no php 5.5 e acima que permitem hash de senha trivialmente simples com bcrypt (já estava na hora!), e há uma biblioteca de compatibilidade com versões anteriores para versões abaixo disso. Geralmente esse hashing volta a envolver uma chamada de sistema linux para menor uso da CPU de qualquer maneira, embora você possa querer garantir que ele esteja instalado em seu servidor. Veja:https://github.com/ircmaxell/password_compat (requer php 5.3.7+) Tenha cuidado ao registrar
Observe que com pg_crypto, as senhas estão em texto simples durante toda a transmissão do navegador para o php e para o banco de dados. Isso significa que eles podem ser registrados em texto simples de consultas se você não for cuidadoso com seus logs de banco de dados. por exemplo. ter um log de consulta lenta postgresql pode capturar e registrar a senha de uma consulta de login em andamento.
Em resumo
Use php bcrypt se puder, isso diminuirá o tempo que a senha permanece sem hash. Tente garantir que seu sistema linux tenha o bcrypt instalado em seu
crypt()
então isso é performático. Atualize para pelo menos o php 5.3.7+ é altamente recomendado, pois a implementação do php é um pouco bugada do php 5.3.0 para 5.3.6.9, e inadequadamente volta para o DES
quebrado sem aviso no php 5.2.9 e inferior. Se você quiser / precisar de hash no postgres, instalar o bcrypt é o caminho a seguir, pois os hashes instalados padrão são antigos e quebrados (md5, etc).
Aqui estão as referências para mais leitura sobre o tema:
- http://codahale.com/how-to-safely-store-a-password/
- http://www.postgresql.org/docs/9.2/static/pgcrypto.html
- https://github.com/ircmaxell/password_compat