Message Digest (hash) è byte [] in byte [] in uscita
Un digest di messaggio è definito come una funzione che accetta un array di byte non elaborato e restituisce un array di byte non elaborato (aka byte[]
). Ad esempio SHA-1 (Secure Hash Algorithm 1) ha una dimensione digest di 160 bit o 20 byte. Gli array di byte non elaborati di solito non possono essere interpretati come codifiche di caratteri come UTF-8 , poiché non tutti i byte di ogni ordine sono legali per la codifica. Quindi convertendoli in a String
con:
new String(md.digest(subject), StandardCharsets.UTF_8)
potrebbe creare alcune sequenze illegali o avere puntatori di codice su mapping Unicode non definiti :
[�a�ɹ??�%l�3~��.
Codifica da binario a testo
Per questo viene utilizzata la codifica da binario a testo . Con gli hash, quello più utilizzato è la codifica HEX o Base16 . Fondamentalmente un byte può avere il valore 0
di 255
(o -128
per 127
firma) che è equivalente alla rappresentazione HEX 0x00
- 0xFF
. Quindi hex raddoppierà la lunghezza richiesta dell'output, il che significa che un output di 20 byte creerà una stringa esadecimale lunga 40 caratteri, ad esempio:
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
Si noti che non è necessario utilizzare la codifica esadecimale. Puoi anche usare qualcosa come base64 . L'esagono è spesso preferito perché è più facile da leggere dall'uomo e ha una lunghezza di uscita definita senza la necessità di imbottitura.
È possibile convertire un array di byte in esadecimale con la sola funzionalità JDK:
new BigInteger(1, token).toString(16)
Si noti tuttavia che BigInteger
interpreterà il dato array di byte come numero e non come stringa di byte. Ciò significa che gli zeri iniziali non verranno emessi e la stringa risultante potrebbe essere inferiore a 40 caratteri.
Utilizzo delle librerie per la codifica in HEX
Ora puoi copiare e incollare un metodo byte-to-hex non testato da Stack Overflow o utilizzare dipendenze enormi come Guava .
Per avere una soluzione di riferimento per la maggior parte dei problemi relativi ai byte ho implementato un'utilità per gestire questi casi: bytes-java (Github)
Per convertire il tuo array di byte digest dei messaggi potresti semplicemente fare
String hex = Bytes.wrap(md.digest(subject)).encodeHex();
oppure potresti semplicemente usare la funzione hash integrata
String hex = Bytes.from(subject).hashSha1().encodeHex();
SHA1
senza il trattino, non so se questo farà la differenza.