I have a problem creating a checksum that matches for OpenSSL and iOS' CommonCrypto implementation. I currently have a .plist file that I want to validate using a checksum. What I have done is the following:
openssl dgst -sha256 file.plist
SHA256(file.plist)= a33184700a1f61f80d4a1d092e83457c9abdf794c20daa276bd3e1e8a4ceb55cAlternatively used the internal shasum function
shasum -a 256 file.plist
a33184700a1f61f80d4a1d092e83457c9abdf794c20daa276bd3e1e8a4ceb55c file.plistSo I now have the sha256 hash of the file. I will create base64 data that can be used in Swift
echo -n 'a33184700a1f61f80d4a1d092e83457c9abdf794c20daa276bd3e1e8a4ceb55c' | xxd -r -p | base64
ozGEcAofYfgNSh0JLoNFfJq995TCDaona9Ph6KTOtVw=So right now, I have the hash and I can use that in iOS. Note that I hashed the exact file that is in Xcode's file inspector.
let calculatedHash = Data(base64Encoded: "ozGEcAofYfgNSh0JLoNFfJq995TCDaona9Ph6KTOtVw=")!
let fileURL = Bundle.main.url(forResource: "file", withExtension: "plist")!
let fileData = try! Data(contentsOf: fileURL)
var hash = Data(count: Int(CC_SHA256_DIGEST_LENGTH))
hash.withUnsafeMutableBytes { hashBuffer in
fileData.withUnsafeBytes { buffer in
_ = CC_SHA256(buffer.baseAddress!, CC_LONG(buffer.count), hashBuffer.bindMemory(UInt8.self).baseAddress)
}
}
print(caluclatedHash as NSData)
print(hash as NSData)
// <a3318470 0a1f61f8 0d4a1d09 2e83457c 9abdf794 c20daa27 6bd3e1e8 a4ceb55c>
// <96d172a8 48235f59 66ff2af3 dae8220d df33f0aa 3be78c46 9d5a18e4 9c73aecd>As you can see, the output is different for the iOS hash. Why is that and how do I solve it?
Thanks in advance!
Craz1k0ek
Solved by using a python library.
import plistlib
import hashlib
def calc_hash(file_name):
try:
f = open(file_name, 'r')
f_data = f.read()
f.close()
file = plistlib.loads(f_data.encode())
except (ValueError, Exception) as e:
print("Failed to load file {}".format(file_name))
return
dump = plistlib.dumps(file, fmt=plistlib.FMT_BINARY)
hasher = hashlib.sha256()
hasher.update(dump)
digest = hasher.digest()
print("{} {}".format(file_name, digest.hex()))
file_name = str(input('Please enter the relative path to the plist (i.e. path/to/plist.plist):\n'))
calc_hash(file_name)