18

I'm trying to use CC_SHA256_DIGEST_LENGTH in one of my functions in Swift and it throws an error because it cannot find that symbol. I've tried everything, importing CommonCrypto in the bridge-header and trying that .map solution.. Nothing works.

How can I use CC_SHA256_DIGEST_LENGTH in Swift? All the solutions seems to have stopped working. Thank you!

Hjalmar
  • 1,921
  • 2
  • 16
  • 19

2 Answers2

42

Add the following line to your bridging header:
#import <CommonCrypto/CommonHMAC.h>

Swift 2.x example:

func doSha256(#dataIn:NSData) -> NSData {
    var shaOut: NSMutableData! = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH));
    CC_SHA256(dataIn.bytes, CC_LONG(dataIn.length), UnsafeMutablePointer<UInt8>(shaOut.mutableBytes));

    return shaOut;
}

Swift 3.0 example:

func hashSHA256(data:Data) -> Data? {
    var hashData = Data(count: Int(CC_SHA256_DIGEST_LENGTH))
    _ = hashData.withUnsafeMutableBytes {digestBytes in
        data.withUnsafeBytes {messageBytes in
            CC_SHA256(messageBytes, CC_LONG(data.count), digestBytes)
        }
    }
    return hashData
}

let clearData   = "clearData0123456".data(using:String.Encoding.utf8)!
print("clearData: \(clearData.map { String(format: "%02hhx", $0) }.joined())")

let hash = hashSHA256(data:clearData)
print("hash: \(hash!.map { String(format: "%02hhx", $0) }.joined())")

Output:

clearData: 636c6561724461746130313233343536
hash: aabc766b6b357564e41f4f912d494bccbfa16924b574abbdba9e3e9da0c8920a

I don't have any frameworks added in the target Build Phases.
Be are you sure that the bridging-header is set up correctly? I added mine by adding a .m file and let the system automatically add the bridging-header and update any target settings.

General hash method moved from the sunsetted documentation section:

This function takes a hash name and Data to be hashed and returns a Data:

name: A name of a hash function as a String  
data: The Data to be hashed  
returns: the hashed result as Data  
func hash(name:String, data:Data) -> Data? {
    let algos = ["MD2":    (CC_MD2,    CC_MD2_DIGEST_LENGTH),
                 "MD4":    (CC_MD4,    CC_MD4_DIGEST_LENGTH),
                 "MD5":    (CC_MD5,    CC_MD5_DIGEST_LENGTH),
                 "SHA1":   (CC_SHA1,   CC_SHA1_DIGEST_LENGTH),
                 "SHA224": (CC_SHA224, CC_SHA224_DIGEST_LENGTH),
                 "SHA256": (CC_SHA256, CC_SHA256_DIGEST_LENGTH),
                 "SHA384": (CC_SHA384, CC_SHA384_DIGEST_LENGTH),
                 "SHA512": (CC_SHA512, CC_SHA512_DIGEST_LENGTH)]
    guard let (hashAlgorithm, length) = algos[name]  else { return nil }
    var hashData = Data(count: Int(length))

    _ = hashData.withUnsafeMutableBytes {digestBytes in
        data.withUnsafeBytes {messageBytes in
            hashAlgorithm(messageBytes, CC_LONG(data.count), digestBytes)
        }
    }
    return hashData
}

Note: MD2, MD4, MD5 and SHA1 should not be used in new work, they are no longer secure for message digest usage.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Still getting the error "Use of unresolved identifier 'CC_SHA256_DIGEST_LENGTH'" as well as the same errors for CC_LONG and CC_SHA256. I have the CommonCrypto import in the bridge-header. Do I need to add any frameworks to the project? Can't get this to work :( – Hjalmar Oct 19 '14 at 15:51
  • FINALLY! The problem was that one of the targets were not ticked when I imported the .m-file to generate a bridging header. Thanks for your help! – Hjalmar Oct 19 '14 at 16:32
  • found it: http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/ oh, also important https://stackoverflow.com/questions/26096402/xcode-myprojectname-bridging-header-h-does-not-exist – pete Jul 15 '17 at 21:10
  • @Panda Thanks for finding the link to the sunsetted documentation section. I have added that to the answer. – zaph Sep 19 '17 at 15:31
  • 6
    In Swift 4.X " import CommonCrypto" not #import – Naresh Jan 05 '19 at 11:30
  • Or (for Swift 4+) `import CommonCrypto.CommonHMAC` – Hari Honor Mar 15 '21 at 15:00
  • confirmed "#import CommonCrypto" for Swift 5.x on Xcode 14. – ingconti Apr 26 '23 at 08:00
2

None of the above worked for me. here is what's worked for swift5:

import CryptoKit
import CommonCrypto

Then:

let hash = SHA256.hash(data: data). 
us_david
  • 4,431
  • 35
  • 29