Preciso fazer hash de senhas para armazenamento em um banco de dados. Como posso fazer isso em Java?
Eu esperava pegar a senha de texto sem formatação, adicionar um sal aleatório e armazenar o sal e a senha com hash no banco de dados.
Então, quando um usuário queria fazer login, eu podia pegar a senha enviada, adicionar o sal aleatório das informações da conta, fazer hash e ver se isso equivale à senha hash armazenada com as informações da conta.
java
passwords
cryptographic-hash-function
Chris Dutrow
fonte
fonte
Respostas:
Você pode realmente usar um recurso incorporado ao tempo de execução Java para fazer isso. O SunJCE no Java 6 suporta PBKDF2, que é um bom algoritmo para usar no hash de senha.
Aqui está uma classe de utilitário que você pode usar para autenticação de senha PBKDF2:
fonte
BigInteger
: zeros à esquerda são removidos. Não há problema em depurar rapidamente, mas vi bugs no código de produção devido a esse efeito.Aqui está uma implementação completa com dois métodos, fazendo exatamente o que você deseja:
O ponto é que, mesmo que um invasor obtenha acesso ao banco de dados e ao código-fonte, as senhas ainda estarão seguras.
Estamos armazenando
'salt$iterated_hash(password, salt)'
. O salt tem 32 bytes aleatórios e seu objetivo é que, se duas pessoas diferentes escolherem a mesma senha, as senhas armazenadas ainda parecerão diferentes.O
iterated_hash
basicamentehash(hash(hash(... hash(password, salt) ...)))
custa muito para um invasor em potencial que tenha acesso ao seu banco de dados adivinhar senhas, fazer hash e procurar hashes no banco de dados. Você precisa calcular issoiterated_hash
toda vez que um usuário faz login, mas não custa muito em comparação com o invasor que gasta quase 100% de seu tempo computando hashes.fonte
char[] password
vez deString password
.O BCrypt é uma biblioteca muito boa e existe uma porta Java .
fonte
Você pode usar a implementação da biblioteca Shiro (anteriormente JSecurity ) do que é descrito pelo OWASP .
Também parece que a biblioteca JASYPT tem um utilitário semelhante .
fonte
Você pode calcular hashes usando
MessageDigest
, mas isso está errado em termos de segurança. Hashes não devem ser usados para armazenar senhas, pois são facilmente quebráveis.Você deve usar outro algoritmo como bcrypt, PBKDF2 e scrypt para armazenar suas senhas. Veja aqui .
fonte
Além de bcrypt e PBKDF2 mencionados em outras respostas, eu recomendaria examinar scrypt
MD5 e SHA-1 não são recomendados, pois são relativamente rápidos, portanto, usando a computação distribuída "aluguel por hora" (por exemplo, EC2) ou uma GPU de ponta moderna, pode-se "quebrar" senhas usando ataques de força bruta / dicionário a custos relativamente baixos e razoáveis Tempo.
Se você precisar usá-los, pelo menos itere o algoritmo uma quantidade significativa predefinida de vezes (mais de 1000).
Veja aqui para mais informações: /security/211/how-to-security-hash-passwords
E aqui: http://codahale.com/how-to-safely-store-a-password/ (critica a família SHA, MD5 etc. para fins de hash de senha)
fonte
Concordo plenamente com Erickson que PBKDF2 é a resposta.
Se você não tiver essa opção ou apenas precisar usar um hash, o Apache Commons DigestUtils é muito mais fácil do que acertar o código JCE: https://commons.apache.org/proper/commons-codec/apidocs/org/apache /commons/codec/digest/DigestUtils.html
Se você usar um hash, use sha256 ou sha512. Esta página tem boas recomendações sobre manipulação e hash de senhas (observe que não recomenda hash para manipulação de senhas): http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
fonte
Você pode usar o Spring Security Crypto (possui apenas 2 dependências de compilação opcionais ), que suporta criptografia de senha PBKDF2 , BCrypt , SCrypt e Argon2 .
fonte
Embora a recomendação NIST PBKDF2 já tenha sido mencionada, gostaria de salientar que houve uma competição de hash de senha pública que foi realizada de 2013 a 2015. No final, o Argon2 foi escolhido como a função de hash de senha recomendada.
Há uma ligação Java bastante bem adotada para a biblioteca original (C nativa) que você pode usar.
No caso de uso médio, acho que não importa da perspectiva de segurança se você escolher PBKDF2 em vez de Argônio2 ou vice-versa. Se você possui fortes requisitos de segurança, recomendo considerar o Argônio2 em sua avaliação.
Para obter mais informações sobre a segurança das funções de hash de senha, consulte security.se .
fonte
Aqui você tem dois links para o hash MD5 e outros métodos de hash:
API Javadoc: https://docs.oracle.com/javase/1.5.0/docs/api/java/security/MessageDigest.html
Tutorial: http://www.twmacinta.com/myjava/fast_md5.php
fonte
Entre todos os esquemas de hash padrão, o LDAP ssha é o mais seguro de usar,
http://www.openldap.org/faq/data/cache/347.html
Gostaria apenas de seguir os algoritmos especificados lá e usar o MessageDigest para fazer o hash.
Você precisa armazenar o sal no seu banco de dados, conforme sugerido.
fonte
A partir de 2020, o algoritmo mais confiável e flexível em uso,
o mais provável de otimizar sua força, considerando qualquer hardware,
é Argon2id ou Argon2i .
Ele fornece a ferramenta de calibração necessária para encontrar parâmetros de força otimizados, considerando um tempo de hash desejado e o hardware usado.
O hashing ganancioso de memória ajudaria contra o uso da GPU para quebrar.
A segurança da primavera / a implementação do castelo insuflável não é otimizada e relativamente uma semana, considerando o que o invasor poderia usar. cf: documentação do Spring
A implementação mais credível em uso para java é a do mkammerer ,
uma jarra / biblioteca de wrapper da implementação nativa oficial escrita em Rust.
É bem escrito e simples de usar.
A versão incorporada fornece versões nativas para Linux, Windows e OSX.
Como exemplo, ele é usado pelo jpmorganchase em seu projeto de segurança de tessera usado para proteger o Quorum , sua implementação de criptomoeda Ethereum.
Aqui está o código de exemplo do tessera.
A calibração pode ser realizada usando de.mkammerer.argon2.Argon2Helper # findIterations
Os algoritmos SCRYPT e Pbkdf2 também podem ser calibrados, escrevendo alguns benchmarks simples, mas os valores mínimos atuais das iterações seguras exigirão tempos de hash mais altos.
fonte
Inclinei isso de um vídeo no udemy e editei para ser uma senha aleatória mais forte
fonte