I am trying to generate a hash similar to one generated in java code so that they can be compared to check for duplicates later in database.
This is how the java code generates it:
public String getHash(String algorithm, String message, String salt) throws NoSuchAlgorithmException {
// Create MessageDigest instance for given algorithm
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes());
byte[] bytes = md.digest(message.getBytes());
// Convert it to hexadecimal format
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i ) {
sb.append(Integer.toString((bytes[i] & 0xff) 0x100, 16)
.substring(1));
}
return sb.toString();
}
This is how I have written in Go:
func HashSha512(original string) (string, error) {
salt := "abcde687869"
originalStrBytes := []byte(original)
sha512Hasher := sha512.New()
saltedValueBytes := append(originalStrBytes, []byte(salt)...)
sha512Hasher.Write(saltedValueBytes)
hashedBytes := sha512Hasher.Sum(nil)
s := ""
var x uint64 = 0x100
y := byte(x)
for i := 0; i < len(hashedBytes); i {
s = fmt.Sprintf("%x", ((hashedBytes[i] & 0xff) y))[1:]
}
return s, nil
}
But the strings generated are not the same.
Go playground link: https://play.golang.com/p/uXaw7y2tklN
String generated is
99461a225184c478b8398c7f0dcc1d3afed107660d08a7282a10f5e2ab6
The string generated for same string in java is
020e93364e5186b7d4ac211cd116425234937d390fcc4e1c554fa1e4bafcb934493047ab841e06f00aa28aabee43b737a6bae2f3fc52e431dde724e691aa952d
What am I doing wrong?
CodePudding user response:
The Go code hashes message salt. The Java code hashes salt message. Swap the order in the Go code to match the Java code.
Use integer values instead of bytes in the conversion to hex. The 0x100 is converted to zero when using bytes:
s = fmt.Sprintf("%x", ((int(hashedBytes[i]) & 0xff) 0x100))[1:]
Better yet, use a library function for the conversion. Using encoding/hex:
return hex.EncodeToString(hashedBytes)
Using fmt:
return fmt.Sprintf("%x", hashedBytes)
There may be a difference in how the strings are encoded to bytes. The Java code uses the platform's default charset. Assuming that the Go application uses UTF-8 encode strings as is typical, the converted bytes are UTF-8 encoded.
Here's a simpler version of the function:
func HashSha512hex(original string) (string, error) {
salt := "abcde6786"
h := sha512.New()
io.WriteString(h, salt)
io.WriteString(h, original)
s := h.Sum(nil)
return hex.EncodeToString(s), nil
}