1

So I try to get the hash from a file. Using the CryptoSwift library. The truth is the variable with the hash that I got from the VLC website, so that should be true. However, the hash I generate is different from the hash I know to be the truth.

Which step do I miss?

Code:

let filePath = "/Users/pjc/Desktop/vlc-3.0.0.dmg"

let fileURL = URL(fileURLWithPath: filePath)
let truth = "e6f7179cb06809b6101803da3ac4191edb72ecf82f31b8ae7dbf010e1a78ba26"

do {
   let fileData = try Data.init(contentsOf: fileURL)
   print(fileData)
   let fileBytes = fileData.bytes
   let hash = fileBytes.sha256()
   print(hash.debugDescription)

} catch {

   //handle error
   print(error)
}

print(hash)
print(truth)

Log:

fileData: 46818658 bytes
hash.debugDescription: [230, 247, 23, 156, 176, 104, 9, 182, 16, 24, 3, 218, 58, 196, 25, 30, 219, 114, 236, 248, 47, 49, 184, 174, 125, 191, 1, 14, 26, 120, 186, 38]
hash: 105553117580736
truth: e6f7179cb06809b6101803da3ac4191edb72ecf82f31b8ae7dbf010e1a78ba26
  • 1
    Hint: 230 = 0xE6, 247 = 0xF7, 23 = 0x17, ... – Martin R Mar 05 '18 at 20:43
  • 1
    I am not familiar with the CryptoSwift library, but from a quick glance at the README, `.toHexString()` may already be what you are looking for. – Martin R Mar 05 '18 at 20:47
  • @MartinR `.toHexString()` does the trick indeed. If you make it an answer I will accept it. Thank you very much! –  Mar 05 '18 at 21:07
  • 2
    I have answered your immediate question, but you might have a look at this answer from someone who knows more about encryption than I do: https://stackoverflow.com/a/34474304/1187415, and use Apple's CommonCrypto instead. – Martin R Mar 05 '18 at 21:19
  • 1
    It is best to avoid using CryptoSwift, amoung other things it is 500 to 1000 times slower than Common Crypto based implementations. Apple's Common Crypto is FIPS certified and as such has been well vetted, using CryptoSwift is taking a chance on correctness and security such as timing and power attacks. – zaph Mar 05 '18 at 21:40

2 Answers2

3

A framework is not necessary to calculate hashes. You can do everything with CommonCrypto. You just need to add a bridging header containing

#import <CommonCrypto/CommonCrypto.h>

You can look up here how to add the bridging header.

extension Data {

    var hexString: String {
        return map { String(format: "%02hhx", $0) }.joined()
    }

    var sha256: Data {
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        self.withUnsafeBytes({
            _ = CC_SHA256($0, CC_LONG(self.count), &digest)
        })
        return Data(bytes: digest)
    }

}
sundance
  • 2,930
  • 1
  • 20
  • 25
3
[230, 247, 23, 156, 176, 104, 9, 182, 16, 24, 3, 218, 58, 196, 25, 30, 219, 114, 236, 248, 47, 49, 184, 174, 125, 191, 1, 14, 26, 120, 186, 38]

and

e6f7179cb06809b6101803da3ac4191edb72ecf82f31b8ae7dbf010e1a78ba26

are just two different representations of the same hash value: The first as an array of integers, the second as a string with the hexadecimal representation of the bytes.

The .toHexString() method of the CryptoSwift library creates a hex string from the array, therefore

print(hash.toHexString())

should produce the expected result.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382