2011-09-30 10 views
10

Tengo una tabla SQL con nombres de usuario y contraseñas. Las contraseñas están codificadas usando el método digest() de MessageDigest. Si codigo una contraseña - digamos "abcdef12" - con el método digest() de MessageDigest y luego la convierto en valores hexadecimales, el String es diferente que si hago lo mismo usando el método SHA1 de PHP. Sin embargo, espero que estos valores sean exactamente los mismos.El algoritmo MessageDigest SHA1 de Java arroja resultados diferentes a los de la función SHA1 de php

código que se utiliza para codificar las contraseñas:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
byte[] passbyte; 
passbyte = "abcdef12".getBytes("UTF-8"); 
passbyte = md.digest(passbyte); 

La conversión de la cadena en hexadecimal se realiza utilizando este método:

public static String convertStringToHex(String str) { 

    char[] chars = str.toCharArray(); 

    StringBuffer hex = new StringBuffer(); 
    for (int i = 0; i < chars.length; i++) { 
     hex.append(Integer.toHexString((int) chars[i])); 
    } 

    return hex.toString(); 
} 

Contraseña: ABCDEF12

Aquí es la contraseña devuelta por muchos generadores en línea SHA1-hash y PHP SHA1() - función: d253e3b d69ce1e7ce6074345fd5faa1a3c2e89ef

Ésta es la contraseña codificada por MessageDigest: d253e3bd69ce1e7ce674345fd5faa1a3c2e2030ef

Estoy olvidando algo?

Igor.

Editar: He encontrado a alguien con un problema similar: C# SHA-1 vs. PHP SHA-1...Different Results?. La solución fue cambiar las codificaciones ... pero no puedo cambiar las codificaciones en el lado del servidor ya que las contraseñas en esa tabla SQL no son creadas por mi aplicación. Uso la codificación SHA1 del lado del cliente utilizando una clase SHA1 de JavaScript (más precisamente: una clase Google Web Toolkit). Funciona y codifica la cadena como se esperaba, pero al parecer el uso de caracteres ASCII ..

Respuesta

3

No tiene nada que ver con las codificaciones. La salida sería completamente diferente.

Para principiantes, su función convertStringToHex() no genera ceros a la izquierda, es decir, 07 se convierte en 7.

El resto (cambiando 89 a 2030) también es probable que tenga algo que ver con esa función. Intente mirar el valor de passbyte después de passbyte = md.digest(passbyte);.

+0

¡Gracias! Tu respuesta resolvió mi problema. ¡Fallé al convertir correctamente la matriz de bytes a una cadena hexadecimal! ¡Utilicé el método de @stivlo y funcionó de maravilla! Voy a marcar esta respuesta como correcta, aunque en este caso desearía poder marcar ambas respuestas como la correcta. ¡Gracias a los dos! – Igor

5

tengo el mismo implícita como PHP con mi Java SHA-1 función hash:?

public static String computeSha1OfString(final String message) 
    throws UnsupportedOperationException, NullPointerException { 
     try { 
       return computeSha1OfByteArray(message.getBytes(("UTF-8"))); 
     } catch (UnsupportedEncodingException ex) { 
       throw new UnsupportedOperationException(ex); 
     } 
} 

private static String computeSha1OfByteArray(final byte[] message) 
    throws UnsupportedOperationException { 
     try { 
      MessageDigest md = MessageDigest.getInstance("SHA-1"); 
      md.update(message); 
      byte[] res = md.digest(); 
      return toHexString(res); 
     } catch (NoSuchAlgorithmException ex) { 
      throw new UnsupportedOperationException(ex); 
     } 
} 

he añadido a mi pruebas unitarias:

String sha1Hash = StringHelper.computeSha1OfString("abcdef12"); 
assertEquals("d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef", sha1Hash); 

código fuente completo para la clase es on github.

+0

De hecho - su código produce la corrige SHA1 (o más bien: lo mismo que SHA1 de php). Sin embargo, estoy escribiendo una aplicación que debe iniciar sesión en una base de datos existente. Esa base de datos no es creada por mí mismo (ni tampoco es el cifrado de la contraseña). Pero ** usa el MessageDigest como está escrito en mi ejemplo ** y, por lo tanto, ejecutando Base64.decode en esa cadena devuelve un resultado diferente (el especificado en mi ejemplo) en lugar de su resultado correcto, que también obtengo usando ese JavaScript SHA1- clase. ¿Hay alguna forma de compararlos? No sé cómo devolvió MessageDigest ese otro resultado. – Igor

2

Prueba esto - que está trabajando para mí:

MessageDigest md = MessageDigest.getInstance(algorithm); 
md.update(original.getBytes()); 
byte[] digest = md.digest(); 
StringBuffer sb = new StringBuffer(); 
for (byte b : digest) { 
    sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); 
} 
return sb.toString(); 

Saludos, Konki

2

O intente esto:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
md.update(clearPassword.getBytes("UTF-8")); 
return new BigInteger(1 ,md.digest()).toString(16)); 

Saludos Roy