2011-09-30 15 views
10

Ho una tabella SQL con nomi utente e password. Le password sono codificate usando il metodo digest() di MessageDigest. Se codifico una password - diciamo "abcdef12" - con il metodo digest() di MessageDigest e poi la converto in valori esadecimali, la stringa è diversa da quella che faccio se faccio lo stesso usando il metodo SHA1 di PHP. Mi aspetto che questi valori siano esattamente gli stessi però.L'algoritmo MessageDigest SHA1 di Java restituisce risultati diversi dalla funzione SHA1 di php

codice che viene utilizzato per codificare le password:

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

La conversione della stringa esadecimale è fatto con questo metodo:

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(); 
} 

Password: ABCDEF12

Ecco la password restituita da molti generatori online SHA1-hash e PHP SHA1() - funzione: d253e3b d69ce1e7ce6074345fd5faa1a3c2e89ef

Ecco la password come codificato da MessageDigest: d253e3bd69ce1e7ce674345fd5faa1a3c2e2030ef

sto dimenticando qualcosa?

Igor.

Modifica: ho trovato qualcuno con un problema simile: C# SHA-1 vs. PHP SHA-1...Different Results?. La soluzione era cambiare le codifiche ... ma non posso cambiare le codifiche sul lato server poiché le password in quella tabella SQL non sono create dalla mia applicazione. Uso la codifica SHA1 lato client utilizzando una classe SHA1 JavaScript (più precisamente: una classe di Google Web Toolkit). Funziona e codifica la stringa come previsto, ma a quanto pare utilizzando caratteri ASCII ..

risposta

3

Non ha nulla a che fare con le codifiche. L'output sarebbe completamente diverso.

Per gli starter, la funzione convertStringToHex() non emette zeri iniziali, ovvero 07 diventa solo 7.

Anche il resto (modifica di 89 a 2030) ha qualcosa a che fare con quella funzione. Prova a guardare il valore di passbyte dopo passbyte = md.digest(passbyte);.

+0

Grazie! La tua risposta ha risolto il mio problema. Stavo fallendo nel convertire correttamente l'array di byte in una stringa esadecimale! Ho usato il metodo da @stivlo e ha funzionato alla grande! Segnerò questa risposta come corretta, anche se in questo caso vorrei poter contrassegnare entrambe le risposte date come corrette! Grazie ad entrambi! – Igor

5

Ho lo stesso digest di PHP con il mio Java SHA-1 funzione di hashing:?

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); 
     } 
} 

ho aggiunto alla mia unit test:

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

il codice sorgente completo per la classe è on github.

+0

Infatti - il codice produce il correggere SHA1 (o meglio: lo stesso di SHA1 di php). Tuttavia, sto scrivendo un'applicazione che deve accedere a un database esistente. Quel database non è stato creato da me (e nemmeno la crittografia della password). Ma ** usa MessageDigest come scritto nel mio esempio ** e quindi eseguire Base64.decode su quella String restituisce un risultato diverso (quello specificato nel mio esempio) piuttosto che il risultato corretto, che anch'io ottengo usando quel JavaScript SHA1- classe. C'è un modo per confrontarli? Non so come MessageDigest restituisse quell'altro risultato. – Igor

2

Prova questo - si sta lavorando per me:

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(); 

saluti, Konki

2

Oppure provate questo:

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

Acclamazioni Roy