Estoy tratando de hacer un simple convertidor de Cadena a SHA1 en Java y esto es lo que tengo ...
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));
}
Cuando lo paso toSHA1("password".getBytes())
, [�a�ɹ??�%l�3~��.
sé que probablemente sea una solución de codificación simple como UTF-8, pero ¿alguien podría decirme qué debo hacer para obtener lo que quiero 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
? ¿O estoy haciendo esto completamente mal?
SHA1
guión, no sé si eso hará la diferencia.getBytes()
, por ejemplo, usetoSHA1("password".getBytes("UTF-8"))
Respuestas:
ACTUALIZACIÓN
Puede usar Apache Commons Codec (versión 1.7+) para hacer este trabajo por usted.
Gracias a @ Jon Onstott por esta sugerencia.
Respuesta anterior
Convierta su matriz de bytes en una cadena hexadecimal. Real's How To te dice cómo .
y (copiado de Real's How To)
Por cierto, puede obtener una representación más compacta usando Base64. Apache Commons Codec API 1.4 , tiene esta buena utilidad para eliminar todo el dolor. consulte aquí
fuente
DigestUtils.sha1Hex("my string")
lugar de reinventar la rueda (aunque es interesante saber cómo convertir a hexágono a mano)?Esta es mi solución de convertir cadenas a sha1. Funciona bien en mi aplicación de Android:
fuente
encryptPassword("test")
yecho test|sha1sum
en la salida del terminal de Linux el mismo resultado? Ellos no.echo test
, se canalizará la salida que incluye un salto de líneasha1sum
. Si desea hacer un hash de una cadena sin saltos de línea, puede usarecho -n test | sha1sum
. El-n
parámetro haceecho
omitir el salto de línea.encryptPassword()
parece que se usa para almacenar datos de autenticación. Tenga en cuenta que su codificación es vulnerable a los ataques de diccionario, ya que no se aplica ninguna inicialización. ¡Compruebe su entorno de seguridad si esto es un problema para su aplicación!Usando la clase Hashing de guayaba :
fuente
SHA-1 (y todos los demás algoritmos de hashing) devuelven datos binarios. Eso significa que (en Java) producen a
byte[]
. Esebyte
conjunto no representa ningún carácter específico, lo que significa que no puede simplemente convertirlo en algoString
como lo hizo.Si necesita un
String
, entonces debe formatearlobyte[]
de una manera que pueda representarse como unString
(de lo contrario, solo mantenga elbyte[]
alrededor).Dos formas comunes de representar caracteres arbitrarios
byte[]
como imprimibles son BASE64 o cadenas hexadecimales simples (es decir, cada una representadabyte
por dos dígitos hexadecimales). Parece que estás tratando de producir una cadena hexadecimal.También hay otro inconveniente: si desea obtener el SHA-1 de un Java
String
, entonces debe convertirloString
en unbyte[]
primero (ya que la entrada de SHA-1 también es unabyte[]
). Si simplemente usamyString.getBytes()
lo que mostró, usará la codificación predeterminada de la plataforma y, como tal, dependerá del entorno en el que lo ejecute (por ejemplo, podría devolver datos diferentes según el idioma / configuración regional de su sistema operativo).Una solución mejor es para especificar la codificación a utilizar para la
String
-a--byte[]
conversión como esto:myString.getBytes("UTF-8")
. Elegir UTF-8 (u otra codificación que pueda representar todos los caracteres Unicode) es la opción más segura aquí.fuente
Esta es una solución simple que se puede usar al convertir una cadena a un formato hexadecimal:
fuente
Simplemente use la biblioteca de códec de apache commons. Tienen una clase de utilidad llamada DigestUtils
No es necesario entrar en detalles.
fuente
String result = DigestUtils.sha1Hex("An input string")
o)Como se mencionó anteriormente, use el códec de apache commons. También lo recomiendan los chicos de Spring (ver DigestUtils en Spring doc). P.ej:
Definitivamente no usaría la respuesta mejor calificada aquí.
fuente
No se imprime correctamente porque necesita usar la codificación Base64. Con Java 8 puede codificar utilizando la clase de codificador Base64 .
Resultado
Esto le dará su salida esperada de
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
fuente
El resumen del mensaje (hash) es byte [] in byte [] out
Un resumen de mensaje se define como una función que toma un conjunto de bytes sin formato y devuelve un conjunto de bytes sin formato (también conocido como
byte[]
). Por ejemplo, SHA-1 (Algoritmo de hash seguro 1) tiene un tamaño de resumen de 160 bits o 20 bytes. Las matrices de bytes sin procesar generalmente no se pueden interpretar como codificaciones de caracteres como UTF-8 , porque no todos los bytes en cada orden son legales. Entonces convertirlos a aString
con:puede crear algunas secuencias ilegales o tiene punteros de código para asignaciones Unicode indefinidas :
Codificación de binario a texto
Para eso se utiliza la codificación de binario a texto . Con los hashes, el que más se usa es la codificación HEX o Base16 . Básicamente, un byte puede tener el valor de
0
a255
(o-128
con127
signo) que es equivalente a la representación HEX de0x00
-0xFF
. Por lo tanto, el hexadecimal duplicará la longitud requerida de la salida, eso significa que una salida de 20 bytes creará una cadena hexadecimal de 40 caracteres de longitud, por ejemplo:Tenga en cuenta que no es necesario utilizar la codificación hexadecimal. También podrías usar algo como base64 . A menudo se prefiere el maleficio porque es más fácil de leer por los humanos y tiene una longitud de salida definida sin la necesidad de relleno.
Puede convertir una matriz de bytes a hexadecimal con la funcionalidad JDK sola:
Sin embargo,
BigInteger
tenga en cuenta que interpretará la matriz de bytes dada como un número y no como una cadena de bytes. Eso significa que no se generarán ceros a la izquierda y la cadena resultante puede ser más corta que 40 caracteres.Uso de bibliotecas para codificar en HEX
Ahora podría copiar y pegar un método de byte a hex no probado desde Stack Overflow o usar dependencias masivas como Guava .
Para tener una solución para la mayoría de los problemas relacionados con los bytes, implementé una utilidad para manejar estos casos: bytes-java (Github)
Para convertir su conjunto de bytes de resumen de mensaje, simplemente puede hacer
o simplemente puedes usar la función integrada de hash
fuente
Base 64 Representación de
SHA1
Hash:fuente
La razón por la que esto no funciona es que cuando llamas
String(md.digest(convertme))
, le estás diciendo a Java que interprete una secuencia de bytes encriptados como una cadena. Lo que quieres es convertir los bytes en caracteres hexadecimales.fuente
Convierta la matriz de bytes en una cadena hexadecimal.
fuente