2014-06-27 22 views
5

Se si genera l'hash SHA-256 nella lingua "GO", ottengo un array di byte diverso rispetto all'equivalente Java.L'hash SHA-256 è diverso dall'hash Java SHA-256

Questa è la versione GO:

fmt.Println(getSha256([]byte("5nonce=5"))) 

La matrice risultante si presenta come:

41 79 186 235 199 123 95 226 16 59 51 161 112 245 192 50 21 66 180 250 179 109 153 18 233 148 16 237 156 69 163 150] 

Questo dovrebbe fare lo stesso in codice Java:

MessageDigest md = MessageDigest.getInstance("SHA-256"); 

md.update("5nonce=5".getBytes()); 
byte[] digest = md.digest(); 

Ma i risultati in questo array di byte

[41, 79, -70, -21, -57, 123, 95, -30, 16, 59, 51, -95, 112, -11, -64, 50, 21, 66, -76, -6, -77, 109, -103, 18, -23, -108, 16, -19, -100, 69, -93, -106] 

Perché sono diversi? Come devo cambiare la versione java per funzionare esattamente come la versione Go?

risposta

17

Perché sono diversi?

Non lo sono, davvero. Sono gli stessi bit. È solo che Java non ha byte senza segno, quindi ogni byte con il set di bit più alto è negativo. In ogni caso, vedrai che risultato Java = risultato Go - 256.

Se si convertono entrambi gli array di byte in hex o base64, si vedranno gli stessi risultati.

+0

Grazie, convertendo loro di base64 rende molto più facile confrontarli e sono identici. – jan

4

Here is the Go code che produrrebbe lo stesso risultato:

package main 

import "fmt" 
import "crypto/sha256" 

func main() { 
    sum224 := sha256.Sum256([]byte("5nonce=5")) 
    s := make([]int8, sha256.Size) 
    for i := range sum224 { 
     s[i] = int8(sum224[i]) 
    } 
    fmt.Printf("%d", s) 
} 

[41 79 -70 -21 -57 123 95 -30 16 59 51 -95 112 -11 -64 50 21 66 -76 -6 -77 109 -103 18 -23 -108 16 -19 -100 69 -93 -106] 

Il fmt doc fa menzione:

non c'è 'u' bandiera. I numeri interi sono stampati senza segno se hanno un tipo senza segno.

Dal Numeric Types definisce:

  • byte alias per uint8
  • uint8 l'insieme di tutti gli interi a 8 bit senza segno (da 0 a 255)
  • int8 l'insieme di tutti segno a 8 bit interi (da -128 a 127)

Ecco perché avresti bisogno di convertire byte (senza firma) nel int8 firmato per vedere lo stesso.


Se si aggiunge la codifica Base64 (vedi golang playground), è possibile ottenere un risultato più facile da confrontare:

import "encoding/base64" 

res := base64.StdEncoding.EncodeToString([]byte(sum224[:])) 
fmt.Println(res) 

che restituisce:

KU+668d7X+IQOzOhcPXAMhVCtPqzbZkS6ZQQ7ZxFo5Y=