Para calcular o hash, siga um destes procedimentos:
Alimente toda a entrada como a byte[]e calcule o hash em uma operação com md.digest(bytes).
Alimente MessageDigestum byte[]pedaço de cada vez ligando md.update(bytes). Quando você terminar de adicionar bytes de entrada, calcule o hash com
md.digest().
Uma coisa que não é mencionada aqui e me pegou de surpresa. As classes MessageDigest NÃO são seguras para threads. Se eles forem usados por threads diferentes, basta criar um novo, em vez de tentar reutilizá-los.
Mjarez #
39
Ele usa vários métodos para alterar seu estado interno. Como a falta de segurança do thread pode ser surpreendente?
amigos estão dizendo
90
@Bombe: por que devemos esperar para ter de saber sobre o estado interno de MessageDigest?
Dan Barowy
28
@ DanBarowy bem, você está mudando isso (ou seja, chamando métodos que não retornam valores, mas fazem com que outros retornem valores diferentes).
Bombe
3
@Traubenfuchs MessageDigestpermite que você insira os dados em pedaços. Isso não seria possível com um método estático. Embora você possa argumentar que eles deveriam ter adicionado um de qualquer maneira por conveniência, quando você pode transmitir todos os dados de uma só vez.
user253751
690
A MessageDigestclasse pode fornecer uma instância do resumo MD5.
Ao trabalhar com strings e as classes de criptografia, sempre especifique a codificação na qual você deseja a representação de bytes. Se você apenas a usar string.getBytes(), usará o padrão da plataforma. (Nem todas as plataformas usam os mesmos padrões)
Se você possui muitos dados, consulte o .update(byte[])método que pode ser chamado repetidamente. Em seguida, chame .digest()para obter o hash resultante.
"LATIN1"! = "ASCII" (ou "US-ASCII"). ASCII é um conjunto de caracteres de 7 bits, Latin1 é um conjunto de caracteres de 8 bits. Eles não são os mesmos.
Este tópico também é útil se você precisar converter os bytes resultantes em sequência hexadecimal.
weekens 22/05/12
1
Então, como você converte esse teste em uma string para que possamos inseri-lo no mysql?
Humphrey
2
Melhor ainda, sempre que possível yourString.getBytes(StandardCharsets.UTF_8). Isso evita o manuseio de um UnsupportedEncodingException.
Hummeling Engineering BV
267
Se você realmente deseja a resposta de volta como uma string, em vez de uma matriz de bytes, sempre pode fazer algo assim:
String plaintext ="your text here";MessageDigest m =MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());byte[] digest = m.digest();BigInteger bigInt =newBigInteger(1,digest);String hashtext = bigInt.toString(16);// Now we need to zero pad it if you actually want the full 32 chars.while(hashtext.length()<32){
hashtext ="0"+hashtext;}
@BalusC: Não é verdade, o método BigInteger.toString retornará o número completo na base especificada. 0x0606 será impressa como 606, apenas zeros direita são omitidos,
Aranha
11
Nitpick menor: m.reset () não é necessário logo após chamar getInstance. Mais pequeno: 'seu texto aqui' requer aspas duplas.
David Leppik
A partir do Java 11, você pode usar em hashtext = "0".repeat(32 - hashtext.length()) + hashtextvez do while, para que os editores não avisem que você está fazendo concatenação de cadeias dentro de um loop.
tom
Em vez de m.update (plaintext.getBytes ()); Eu recomendaria especificar a codificação. como m.update (plaintext.getBytes ("UTF-8")); getBytes () não garante a codificação e pode variar de sistema para sistema, o que pode resultar em resultados MD5 diferentes entre sistemas para a mesma String.
user1819780 27/03
256
Você também pode examinar a classe DigestUtils do projeto de codec do apache commons , que fornece métodos muito convenientes para criar resumos MD5 ou SHA.
Em particular, os métodos que retornam representações codificadas "seguras" dos dados de bytes na forma de seqüência de caracteres.
7123 Rob
4
No entanto, não há uma maneira fácil de incluir a classe DigestUtils em seu projeto sem adicionar uma tonelada de bibliotecas ou portar a classe "por mão", o que requer pelo menos mais duas classes.
Iuiz
Também não é possível encontrá-lo em repositórios maven. Grrrr.
Sparkyspider
5
Deve ser nos repositórios centrais Maven, a menos que eu estou ficando louco: GROUPID = commons-codec artifactId = commons-codec versão = 1,5
Nick Spacek
160
Encontrou isto:
publicString MD5(String md5){try{
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");byte[] array = md.digest(md5.getBytes());StringBuffer sb =newStringBuffer();for(int i =0; i < array.length;++i){
sb.append(Integer.toHexString((array[i]&0xFF)|0x100).substring(1,3));}return sb.toString();}catch(java.security.NoSuchAlgorithmException e){}returnnull;}
no site abaixo, não aceito crédito, mas é uma solução que funciona! Para mim, muitos outros códigos não funcionaram corretamente, acabei perdendo 0s no hash. Este parece ser o mesmo que o PHP. fonte: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093
Você deve especificar a codificação a ser usada getBytes(), caso contrário, seu código obterá resultados diferentes em diferentes plataformas / configurações do usuário.
Pa Elo Ebermann
@ PaŭloEbermann faz MessageDigest.getInstance ("MD5"); insuficiente? Eu tentei adicionar "MD5" em getBytes (), mas retornou um erro
chama Tama
2
@BlazeTama "MD5" não é uma codificação, é um algoritmo de compilação de mensagens (e não um que deve ser usado em novos aplicativos). Uma codificação é um par de algoritmos que transforma bytes em cadeias de caracteres e cadeias de caracteres em bytes. Um exemplo seria "UTF-8", "US-ASCII", "ISO-8859-1", "UTF-16BE" e similares. Use a mesma codificação que qualquer outra parte que calcule um hash dessa string, caso contrário você obterá resultados diferentes.
Pa Elo Ebermann 21/02
6
Para um exemplo de conjunto de caracteres ... (use UTF-8, que é o melhor e mais compatível na minha opinião) ...byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Richard
Como não é a minha solução, e eu mesmo não testei todos os cenários, vou deixá-lo inalterado, embora eu ache que especificar a codificação etc seja provavelmente uma boa idéia.
dac2009
88
Aqui está como eu o uso:
finalMessageDigest messageDigest =MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));finalbyte[] resultByte = messageDigest.digest();finalString result =newString(Hex.encodeHex(resultByte));
Este é o método que fornece o mesmo valor de retorno que a função MySQL md5 (str). Muitas das outras respostas retornaram outros valores.
Rwitzel
1
Isso não funciona direito sobre Android porque o Android feixes commons-codec 1.2, para o qual você precisa esta solução alternativa: stackoverflow.com/a/9284092/2413303
EpicPandaForce
76
Eu descobri que essa é a maneira mais clara e concisa de fazer isso:
Ótimo. Não cai na armadilha de cortar zeros à esquerda.
Markus Pscheidt
2
Cuidado, isso não funcionará no Android se você estiver usando o nível da API <19, mas você só precisa alterar a segunda linha com md5.update (string.getBytes ("UTF-8")); Isto irá adicionar mais uma exceção verificada a alça, embora ...
Fran Marzoa
34
Encontrei esta solução que é muito mais limpa em termos de recuperar uma representação de String de um hash MD5.
import java.security.*;import java.math.*;publicclass MD5 {publicstaticvoid main(String args[])throwsException{String s="This is a test";MessageDigest m=MessageDigest.getInstance("MD5");
m.update(s.getBytes(),0,s.length());System.out.println("MD5: "+newBigInteger(1,m.digest()).toString(16));}}
Por que essa resposta é -1 enquanto a outra resposta mais curta e menos descritiva tem +146?
Nilzor
4
Agradável usando BigInteger para obter um valor hexadecimal +1
Dave.B
5
Eu só descobri que em alguns casos isso só gera 31 caracteres MD5 soma, não 32 como deveria ser
kovica
3
@kovica é porque, os zeros iniciais ficam truncados se bem me lembro .. String.format("%032x", new BigInteger(1, hash)); Isso deve resolver isso. 'hash' é o byte [] do hash.
Heshan Perera
Esta resposta tem um erro com o tipo de conjunto de caracteres!
Apenas uma linha que vi que não usa uma biblioteca externa.
21817 holmis83
A menos que eu esteja enganado, isso retorna sempre em maiúsculas, que não se alinham com os md5s feitos sem o uso de hex. Nem mesmo realmente certeza de que ele é um verdadeiro md5
walshie4
2
@ walshie4 não existe MD5 sem hex (veja ietf.org/rfc/rfc1321.txt ), para obtê-lo em minúsculas basta adicionar .toLower (). Compare os resultados com os exemplos em, por exemplo, en.wikipedia.org/wiki/MD5, então você terá uma chance melhor de acreditar que o código da biblioteca Javas está correto.
empilhador
28
Eu tenho uma classe (Hash) para converter texto sem formatação em hash em formatos: md5 ou sha1, simillar que funções php ( md5 , sha1 ):
publicclassHash{/**
*
* @param txt, text in plain format
* @param hashType MD5 OR SHA1
* @return hash in hashType
*/publicstaticString getHash(String txt,String hashType){try{
java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);byte[] array = md.digest(txt.getBytes());StringBuffer sb =newStringBuffer();for(int i =0; i < array.length;++i){
sb.append(Integer.toHexString((array[i]&0xFF)|0x100).substring(1,3));}return sb.toString();}catch(java.security.NoSuchAlgorithmException e){//error action}returnnull;}publicstaticString md5(String txt){returnHash.getHash(txt,"MD5");}publicstaticString sha1(String txt){returnHash.getHash(txt,"SHA1");}}
A resposta de Bombe está correta, no entanto, observe que, a menos que você precise absolutamente usar o MD5 (por exemplo, forçado a interoperabilidade), uma melhor opção é SHA1, pois o MD5 tem pontos fracos para uso a longo prazo.
Devo acrescentar que o SHA1 também tem vulnerabilidades teóricas, mas não tão graves. O estado da arte atual no hash é que existem várias funções de hash de substituição de candidatos, mas nenhuma ainda surgiu como a melhor prática padrão para substituir o SHA1. Portanto, dependendo de suas necessidades, é recomendável que você configure seu algoritmo de hash para que possa ser substituído no futuro.
Você poderia me indicar alguns recursos, onde posso ler sobre méritos e fraquezas relativos de cada um?
Akshay
Provavelmente, o melhor que você pode fazer no momento é usar o SHA1 e estar pronto para substituí-lo no futuro. Você pode usar funções mais novas, mas elas ainda não foram sujeitas a grandes quantidades de pesquisa. Você pode acompanhar os recursos de segurança online para descobrir quando isso muda - por exemplo, o blog de Bruce Schneier.
frankodwyer
7
O SHA1 é um exagero, a menos que você queira um hash criptograficamente seguro, ou seja, não queira que o hash ajude a reconstruir a mensagem original, nem que um invasor inteligente crie outra mensagem que corresponda ao hash. Se o original não é um segredo e o hash não está sendo usado para segurança, o MD5 é rápido e fácil. Por exemplo, o Google Web Toolkit usa hashes MD5 em URLs JavaScript (por exemplo, foo.js? Hash = 12345).
Esta é uma biblioteca sólida e autônoma com dependências mínimas. Coisa boa.
Ajax
Eu achei muito útil. Foram necessários 15357 ms para um arquivo de 4,57 GB, enquanto a implementação embutida em java levou 19094 ms.
bkrish
11
Não sei se isso é relevante para quem está lendo isso, mas só tive o problema que queria
baixar um arquivo de um determinado URL e
compare seu MD5 com um valor conhecido.
Eu queria fazer isso apenas com classes JRE (sem Apache Commons ou similar). Uma pesquisa rápida na Web não me mostrou exemplos de trechos de código duas ao mesmo tempo, apenas cada tarefa separadamente. Como isso requer a leitura do mesmo arquivo duas vezes, achei que poderia valer a pena escrever algum código que unifique as duas tarefas, calculando a soma de verificação em tempo real durante o download do arquivo. Este é o meu resultado (desculpe se não é Java perfeito, mas acho que você entendeu a ideia):
Ah, BTW, antes que alguém, exceto eu, perceba o quão ruim é meu conhecimento em JRE: acabei de descobrir o DigestInputStream e o DigestOutputStream . Vou editar minha solução original para refletir o que acabei de aprender.
kriegaex
6
Dê uma olhada no link a seguir, o Exemplo obtém um Hash MD5 de uma imagem fornecida:
Hash MD5 de uma imagem
Pelo que vale, me deparei com isso porque quero sintetizar GUIDs de uma chave natural para um programa que instalará componentes COM; Quero dimensionar o tamanho para não gerenciar o ciclo de vida do GUID. Vou usar o MD5 e depois a classe UUID para obter uma string. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 levanta esse problema).
De qualquer forma, java.util.UUID pode fornecer uma boa String a partir dos bytes MD5.
na verdade, ele aceita não apenas uma matriz de bytes MD5 (tamanho == 16). Você pode passar a matriz de bytes de qualquer tamanho. Vai ser convertidos em bytes matriz MD5 por meio de MD5 MessageDigest(ver nameUUIDFromBytes () código-fonte )
Ao contrário do PHP, onde você pode fazer um hash MD5 do seu texto, basta chamar a função md5, ou seja md5($text), em Java, isso foi um pouco complicado. Normalmente, eu o implementava chamando uma função que retorna o texto hash md5. Aqui está como eu a implementei: Primeiro crie uma função nomeada md5hashingdentro da sua classe principal, conforme indicado abaixo.
publicstaticString md5hashing(String text){String hashtext =null;try{String plaintext = text;MessageDigest m =MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());byte[] digest = m.digest();BigInteger bigInt =newBigInteger(1,digest);
hashtext = bigInt.toString(16);// Now we need to zero pad it if you actually want the full 32 chars.while(hashtext.length()<32){
hashtext ="0"+hashtext;}}catch(Exception e1){// TODO: handle exceptionJOptionPane.showMessageDialog(null,e1.getClass().getName()+": "+ e1.getMessage());}return hashtext;}
Agora chame a função sempre que necessário, conforme indicado abaixo.
String text = textFieldName.getText();String pass = md5hashing(text);
Aqui você pode ver que o hashtext é anexado com um zero para torná-lo compatível com o hash md5 no PHP.
O MD5 é perfeitamente adequado se você não precisar da melhor segurança e, se estiver fazendo algo como verificar a integridade dos arquivos, a segurança não é uma consideração. Nesse caso, convém considerar algo mais simples e rápido, como o Adler32, que também é suportado pelas bibliotecas Java.
O que faz você pensar que a integridade do arquivo não é um problema de segurança?
Jeremy Huiskamp
5
este dá o md5 exato que você obtém da função md5 do mysql ou das funções md5 do php etc. É esse que eu uso (você pode alterar de acordo com suas necessidades)
Esta é provavelmente a pior solução, pois remove zeros à esquerda.
Jannick
4
import java.security.MessageDigest
val digest =MessageDigest.getInstance("MD5")//Quick MD5 of text
val text ="MD5 this text!"
val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString
//MD5 of text with updates
digest.update("MD5 ".getBytes())
digest.update("this ".getBytes())
digest.update("text!".getBytes())
val md5hash2 = digest.digest().map(0xFF& _).map("%02x".format(_)).mkString
//Output
println(md5hash1 +" should be the same as "+ md5hash2)
Você pode gerar o hash MD5 para um determinado texto usando os métodos da MessageDigestclasse no java.securitypacote. Abaixo está o snippet de código completo,
A saída da função MD5 é um hash de 128 bits representado por 32 números hexadecimais.
Caso esteja usando um banco de dados como o MySQL, você também pode fazer isso de uma maneira mais simples. A consulta Select MD5(“text here”)retornará o hash MD5 do texto entre colchetes.
Respostas:
Você precisa
java.security.MessageDigest
.Ligue
MessageDigest.getInstance("MD5")
para obter uma instância MD5 queMessageDigest
você possa usar.Para calcular o hash, siga um destes procedimentos:
byte[]
e calcule o hash em uma operação commd.digest(bytes)
.MessageDigest
umbyte[]
pedaço de cada vez ligandomd.update(bytes)
. Quando você terminar de adicionar bytes de entrada, calcule o hash commd.digest()
.O
byte[]
retornado pormd.digest()
é o hash MD5.fonte
MessageDigest
permite que você insira os dados em pedaços. Isso não seria possível com um método estático. Embora você possa argumentar que eles deveriam ter adicionado um de qualquer maneira por conveniência, quando você pode transmitir todos os dados de uma só vez.A
MessageDigest
classe pode fornecer uma instância do resumo MD5.Ao trabalhar com strings e as classes de criptografia, sempre especifique a codificação na qual você deseja a representação de bytes. Se você apenas a usar
string.getBytes()
, usará o padrão da plataforma. (Nem todas as plataformas usam os mesmos padrões)Se você possui muitos dados, consulte o
.update(byte[])
método que pode ser chamado repetidamente. Em seguida, chame.digest()
para obter o hash resultante.fonte
yourString.getBytes(StandardCharsets.UTF_8)
. Isso evita o manuseio de umUnsupportedEncodingException
.Se você realmente deseja a resposta de volta como uma string, em vez de uma matriz de bytes, sempre pode fazer algo assim:
fonte
hashtext = "0".repeat(32 - hashtext.length()) + hashtext
vez dowhile
, para que os editores não avisem que você está fazendo concatenação de cadeias dentro de um loop.Você também pode examinar a classe DigestUtils do projeto de codec do apache commons , que fornece métodos muito convenientes para criar resumos MD5 ou SHA.
fonte
Encontrou isto:
no site abaixo, não aceito crédito, mas é uma solução que funciona! Para mim, muitos outros códigos não funcionaram corretamente, acabei perdendo 0s no hash. Este parece ser o mesmo que o PHP. fonte: http://m2tec.be/blog/2010/02/03/java-md5-hex-0093
fonte
getBytes()
, caso contrário, seu código obterá resultados diferentes em diferentes plataformas / configurações do usuário.byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
Aqui está como eu o uso:
onde Hex é:
org.apache.commons.codec.binary.Hex
do projeto Apache Commons .fonte
String result = Hex.encodeHexString(resultByte);
Acabei de baixar commons-codec.jar e obtive um php perfeito como o md5. Aqui está o manual .
Basta importá-lo para o seu projeto e usar
e aí está.
fonte
Eu descobri que essa é a maneira mais clara e concisa de fazer isso:
fonte
Encontrei esta solução que é muito mais limpa em termos de recuperar uma representação de String de um hash MD5.
O código foi extraído daqui .
fonte
String.format("%032x", new BigInteger(1, hash));
Isso deve resolver isso. 'hash' é o byte [] do hash.Outra opção é usar os métodos de Hashing de goiaba :
Prático, se você já estiver usando o Guava (que, se não estiver, provavelmente deveria).
fonte
Hashing.md5().hashString("my string").asBytes();
Outra implementação:
fonte
Eu tenho uma classe (Hash) para converter texto sem formatação em hash em formatos: md5 ou sha1, simillar que funções php ( md5 , sha1 ):
Testando com JUnit e PHP
Script PHP:
Script PHP de saída:
Usando exemplo e Testando com JUnit:
Código no GitHub
fonte
Não há necessidade de torná-lo muito complicado.
O DigestUtils funciona bem e deixa você confortável enquanto trabalha com
md5
hashes.ou
Você pode usar outros métodos de criptografia, como
sha
oumd
.fonte
Minha resposta não muito reveladora:
fonte
String.format("%1$032X", big)
para ter um formato maiúsculoTambém há uma
DigestUtils
classe na primavera :http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/DigestUtils.html
Esta classe contém o método
md5DigestAsHex()
que faz o trabalho.fonte
Você pode tentar seguir. Veja detalhes e códigos de download aqui: http://jkssweetlife.com/java-hashgenerator-md5-sha-1/
fonte
A resposta de Bombe está correta, no entanto, observe que, a menos que você precise absolutamente usar o MD5 (por exemplo, forçado a interoperabilidade), uma melhor opção é SHA1, pois o MD5 tem pontos fracos para uso a longo prazo.
Devo acrescentar que o SHA1 também tem vulnerabilidades teóricas, mas não tão graves. O estado da arte atual no hash é que existem várias funções de hash de substituição de candidatos, mas nenhuma ainda surgiu como a melhor prática padrão para substituir o SHA1. Portanto, dependendo de suas necessidades, é recomendável que você configure seu algoritmo de hash para que possa ser substituído no futuro.
fonte
Outra implementação: Implementação rápida do MD5 em Java
fonte
Não sei se isso é relevante para quem está lendo isso, mas só tive o problema que queria
Eu queria fazer isso apenas com classes JRE (sem Apache Commons ou similar). Uma pesquisa rápida na Web não me mostrou exemplos de trechos de código duas ao mesmo tempo, apenas cada tarefa separadamente. Como isso requer a leitura do mesmo arquivo duas vezes, achei que poderia valer a pena escrever algum código que unifique as duas tarefas, calculando a soma de verificação em tempo real durante o download do arquivo. Este é o meu resultado (desculpe se não é Java perfeito, mas acho que você entendeu a ideia):
fonte
Dê uma olhada no link a seguir, o Exemplo obtém um Hash MD5 de uma imagem fornecida: Hash MD5 de uma imagem
fonte
Pelo que vale, me deparei com isso porque quero sintetizar GUIDs de uma chave natural para um programa que instalará componentes COM; Quero dimensionar o tamanho para não gerenciar o ciclo de vida do GUID. Vou usar o MD5 e depois a classe UUID para obter uma string. (http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439 levanta esse problema).
De qualquer forma, java.util.UUID pode fornecer uma boa String a partir dos bytes MD5.
fonte
MessageDigest
(ver nameUUIDFromBytes () código-fonte )fonte
Ao contrário do PHP, onde você pode fazer um hash MD5 do seu texto, basta chamar a função md5, ou seja
md5($text)
, em Java, isso foi um pouco complicado. Normalmente, eu o implementava chamando uma função que retorna o texto hash md5. Aqui está como eu a implementei: Primeiro crie uma função nomeadamd5hashing
dentro da sua classe principal, conforme indicado abaixo.Agora chame a função sempre que necessário, conforme indicado abaixo.
Aqui você pode ver que o hashtext é anexado com um zero para torná-lo compatível com o hash md5 no PHP.
fonte
O MD5 é perfeitamente adequado se você não precisar da melhor segurança e, se estiver fazendo algo como verificar a integridade dos arquivos, a segurança não é uma consideração. Nesse caso, convém considerar algo mais simples e rápido, como o Adler32, que também é suportado pelas bibliotecas Java.
fonte
este dá o md5 exato que você obtém da função md5 do mysql ou das funções md5 do php etc. É esse que eu uso (você pode alterar de acordo com suas necessidades)
fonte
tente isto:
fonte
fonte
Você pode gerar o hash MD5 para um determinado texto usando os métodos da
MessageDigest
classe nojava.security
pacote. Abaixo está o snippet de código completo,A saída da função MD5 é um hash de 128 bits representado por 32 números hexadecimais.
Caso esteja usando um banco de dados como o MySQL, você também pode fazer isso de uma maneira mais simples. A consulta
Select MD5(“text here”)
retornará o hash MD5 do texto entre colchetes.fonte
Isto é o que eu vim aqui - uma função útil de scala que retorna uma sequência de hash MD5:
fonte
Há um artigo no Codingkit sobre isso. Confira: http://codingkit.com/a/JAVA/2013/1020/2216.html
fonte