3 Replies
      Latest reply on Jun 8, 2019 5:30 PM by Craz1k0ek
      Craz1k0ek Level 1 Level 1 (10 points)

        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)= a33184700a1f61f80d4a1d092e83457c9abdf794c20daa276bd3e1e8a4ceb55c

         

        Alternatively used the internal shasum function

        shasum -a 256 file.plist
        a33184700a1f61f80d4a1d092e83457c9abdf794c20daa276bd3e1e8a4ceb55c  file.plist

         

        So 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

        • Re: Invalid Checksum
          eskimo Apple Staff Apple Staff (11,835 points)

          You are getting this property list from your bundle.  I suspect that the problem here is that the Xcode build system will convert property list files to a binary format, which changes the checksum.  You should dump fileData to make sure it matches what you expect.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

          • Re: Invalid Checksum
            Craz1k0ek Level 1 Level 1 (10 points)

            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)