0

When calculating sha256 in Java and in Swift, it does not match.

Java:

MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(secretKey.getBytes("UTF-8"));

byte[] secretKeyBytes = secretKey.getBytes("UTF-8");

byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);

Result: [44, 112, -31, 43, 122, 6, 70, -7, 34, 121, -12, 39, -57, -77, -114, 115]

Swift:

let secretKeyBytes = [UInt8](secretKey.utf8)

var digest = SHA2(variant: SHA2.Variant.sha256)
try digest.update(withBytes: secretKeyBytes)
let keyDigest = try digest.finish()

let keyBytes = Array(keyDigest[0...15])

Result: [44, 112, 225, 43, 122, 6, 70, 249, 34, 121, 244, 39, 199, 179, 142, 115]

It starts with same values but then it starts to differ

Jakub Gruber
  • 745
  • 1
  • 11
  • 27
  • Your Java code overflows and produces negative values. – Tamás Sengel Oct 09 '17 at 10:58
  • Possible duplicate of [SHA256 Hash results different across Android & iOS for Big numbers](https://stackoverflow.com/questions/39018731/sha256-hash-results-different-across-android-ios-for-big-numbers) – pedrofb Oct 09 '17 at 11:36

1 Answers1

6

Bytes in Java are signed, so they can only represent the values of -128 to 127, as such when it tries to represent 225 (the third byte) it overflows to -31. The actual binary representation of both bytes will be the same 1110 0001.

Justinw
  • 631
  • 10
  • 18
  • Any idea how to solve that without modifying Java code? I cannot change that now. Tried to convert `UInt8` in Swift to `Int8`, but it is not accepted by CryptoSwift library. – Jakub Gruber Oct 09 '17 at 11:13
  • 1
    @JakubGruber, you can map resulting `keyBytes` into `[Int8]` using `Int8(bitPattern:)` – user28434'mstep Oct 09 '17 at 11:20
  • 1
    Well, then keep it in `UInt8` then, binary those two hashes are same. – user28434'mstep Oct 09 '17 at 11:27
  • 4
    So the textual representation of the arrays differ, but the contents of the array (the binary values, represented by the byte values) are identical. As long as you make sure that you compare the binary values directly **or** as long as you compare identical representation of the bytes then you should be good. – Maarten Bodewes Oct 09 '17 at 12:38