Estou tentando fazer um simples conversor de String para SHA1 em Java e é isso que eu tenho ...
public static String toSHA1(byte[] convertme) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
}
catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new String(md.digest(convertme));
}
Quando passo toSHA1("password".getBytes())
, [�a�ɹ??�%l�3~��.
sei que provavelmente é uma correção de codificação simples como UTF-8, mas alguém poderia me dizer o que devo fazer para obter o que quero 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
? Ou estou fazendo isso completamente errado?
SHA1
sem o hífen, não sei se isso fará diferença.getBytes()
, por exemplo utilizaçãotoSHA1("password".getBytes("UTF-8"))
Respostas:
ATUALIZAÇÃO
Você pode usar o Apache Commons Codec (versão 1.7+) para fazer esse trabalho.
Obrigado a Jon Onstott por esta sugestão.
Resposta antiga
Converta seu Byte Array em Hex String. O Real's How To diz como .
e (copiado do Real's How To)
BTW, você pode obter uma representação mais compacta usando o Base64. O Apache Commons Codec API 1.4 , possui esse ótimo utilitário para remover toda a dor. consulte aqui
fonte
DigestUtils.sha1Hex("my string")
vez de reinventar a roda (embora seja interessante saber como converter em hexadecimal manualmente)?Esta é a minha solução de converter string para sha1. Funciona bem no meu aplicativo Android:
fonte
encryptPassword("test")
eecho test|sha1sum
no terminal Linux produzir o mesmo resultado? Eles não.echo test
, a saída incluindo uma quebra de linha será canalizada parasha1sum
. Se você deseja fazer o hash de uma string simples sem quebras de linha à direita, use-oecho -n test | sha1sum
. O-n
parâmetro fazecho
omitir a quebra de linha.encryptPassword()
sons são usados para armazenar dados de autenticação. Observe que sua codificação é vulnerável a ataques de dicionário, pois nenhuma propagação é aplicada. Verifique seu ambiente de segurança se isso é um problema para seu aplicativo!Usando a classe Guava Hashing :
fonte
SHA-1 (e todos os outros algoritmos de hash) retornam dados binários. Isso significa que (em Java) eles produzem a
byte[]
. Essebyte
array não representa nenhum caractere específico, o que significa que você não pode simplesmente transformá-loString
como você fez.Se você precisar de um
String
, precisará formatá-lobyte[]
de uma maneira que possa ser representada como umString
(caso contrário, apenas mantenha o ambientebyte[]
).Duas maneiras comuns de representar
byte[]
caracteres arbitrários como imprimíveis são BASE64 ou Hex-Strings simples (ou seja, representando cada umbyte
por dois dígitos hexadecimais). Parece que você está tentando produzir uma cadeia hexadecimal.Há também outra armadilha: se você deseja obter o SHA-1 de um Java
String
, é necessário convertê-loString
em umbyte[]
primeiro (já que a entrada do SHA-1 também ébyte[]
). Se você simplesmente usarmyString.getBytes()
como mostrou, ele usará a codificação padrão da plataforma e, como tal, dependerá do ambiente em que a executar (por exemplo, pode retornar dados diferentes com base na configuração de idioma / localidade do seu sistema operacional).A melhor solução é especificar a codificação utilizada para a
String
Para-byte[]
conversão como este:myString.getBytes("UTF-8")
. Escolher UTF-8 (ou outra codificação que possa representar todos os caracteres Unicode) é a opção mais segura aqui.fonte
Esta é uma solução simples que pode ser usada ao converter uma string para um formato hexadecimal:
fonte
Basta usar a biblioteca de codecs do apache commons. Eles têm uma classe de utilitário chamada DigestUtils
Não há necessidade de entrar em detalhes.
fonte
String result = DigestUtils.sha1Hex("An input string")
Como mencionado anteriormente, use o codec do apache commons. Também é recomendado pelos caras do Spring (consulte DigestUtils no documento do Spring). Por exemplo:
Definitivamente não usaria a resposta mais votada aqui.
fonte
Não está imprimindo corretamente porque você precisa usar a codificação Base64. Com o Java 8, você pode codificar usando a classe de codificador Base64 .
Resultado
Isso fornecerá a saída esperada de
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
fonte
O Resumo da Mensagem (hash) é byte [] in byte [] out
Um resumo da mensagem é definido como uma função que pega uma matriz de bytes brutos e retorna uma matriz de bytes brutos (aka
byte[]
). Por exemplo, o SHA-1 (algoritmo de hash seguro 1) tem um tamanho de resumo de 160 bits ou 20 bytes. Matrizes de bytes brutos geralmente não podem ser interpretadas como codificações de caracteres como UTF-8 , porque nem todos os bytes em cada ordem são uma codificação legal. Então, convertendo-os em umString
com:pode criar algumas seqüências ilegais ou possui indicadores de código para mapeamentos Unicode indefinidos :
Codificação de binário para texto
Para essa codificação de binário para texto é usada. Com os hashes, o mais usado é a codificação HEX ou Base16 . Basicamente, um byte pode ter o valor de
0
a255
(ou-128
a127
assinatura), que é equivalente à representação de HEX0x00
-0xFF
. Portanto, hex dobrará o comprimento necessário da saída, o que significa que uma saída de 20 bytes criará uma cadeia hexadecimal de 40 caracteres, por exemplo:Observe que não é necessário usar a codificação hexadecimal. Você também pode usar algo como base64 . O hex é frequentemente preferido porque é mais fácil de ser lido por humanos e tem um comprimento de saída definido sem a necessidade de preenchimento.
Você pode converter uma matriz de bytes em hexadecimal apenas com a funcionalidade JDK:
Observe, no entanto, que
BigInteger
interpretará a matriz de bytes fornecida como número e não como uma sequência de bytes. Isso significa que os zeros à esquerda não serão gerados e a sequência resultante poderá ser menor que 40 caracteres.Usando bibliotecas para codificar para HEX
Agora você pode copiar e colar um método não testado de bytes para hexa do Stack Overflow ou usar dependências massivas como o Guava .
Para ter uma solução básica para a maioria dos problemas relacionados a bytes, implementei um utilitário para lidar com estes casos: bytes-java (Github)
Para converter sua matriz de bytes de resumo da mensagem, você pode simplesmente fazer
ou você pode simplesmente usar o recurso de hash embutido
fonte
Representação da Base 64 do
SHA1
Hash:fonte
A razão pela qual isso não funciona é que, quando você liga
String(md.digest(convertme))
, está dizendo ao Java para interpretar uma sequência de bytes criptografados como uma String. O que você deseja é converter os bytes em caracteres hexadecimais.fonte
Converter matriz de bytes em sequência hexadecimal.
fonte