I'm trying to create a HMAC SHA-1 hash of a string in Swift but can't figure out how to interact with the APIs as it doesn't seem to be importing the CommonCrypto framework. I've tried various different forms of "import CommonCrypto" and creating a bridging header file but none of it made a difference.
The odd thing is that if I create an Objective-C class, I'm able to interact with APIs without any problems, so this seems to be unique to Swift.
Also if anyone could tell me what the equivalent of uint8_t digest[CC_SHA1_DIGEST_LENGTH]
is in Swift I'd be very grateful
You can do it in Swift. Just make sure you add #import <CommonCrypto/CommonHMAC.h>
to the bridging Objective-C bridging header.
Update: For Swift 4 see a much better solution using the Swift Package Manager here: https://github.com/jernejstrasner/SwiftCrypto
enum CryptoAlgorithm { case MD5, SHA1, SHA224, SHA256, SHA384, SHA512 var HMACAlgorithm: CCHmacAlgorithm { var result: Int = 0 switch self { case .MD5: result = kCCHmacAlgMD5 case .SHA1: result = kCCHmacAlgSHA1 case .SHA224: result = kCCHmacAlgSHA224 case .SHA256: result = kCCHmacAlgSHA256 case .SHA384: result = kCCHmacAlgSHA384 case .SHA512: result = kCCHmacAlgSHA512 } return CCHmacAlgorithm(result) } var digestLength: Int { var result: Int32 = 0 switch self { case .MD5: result = CC_MD5_DIGEST_LENGTH case .SHA1: result = CC_SHA1_DIGEST_LENGTH case .SHA224: result = CC_SHA224_DIGEST_LENGTH case .SHA256: result = CC_SHA256_DIGEST_LENGTH case .SHA384: result = CC_SHA384_DIGEST_LENGTH case .SHA512: result = CC_SHA512_DIGEST_LENGTH } return Int(result) } } extension String { func hmac(algorithm: CryptoAlgorithm, key: String) -> String { let str = self.cStringUsingEncoding(NSUTF8StringEncoding) let strLen = Int(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) let digestLen = algorithm.digestLength let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen) let keyStr = key.cStringUsingEncoding(NSUTF8StringEncoding) let keyLen = Int(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result) let digest = stringFromResult(result, length: digestLen) result.dealloc(digestLen) return digest } private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String { var hash = NSMutableString() for i in 0..<length { hash.appendFormat("%02x", result[i]) } return String(hash) } }
Try this for Swift 3.1 :
enum CryptoAlgorithm { case MD5, SHA1, SHA224, SHA256, SHA384, SHA512 var HMACAlgorithm: CCHmacAlgorithm { var result: Int = 0 switch self { case .MD5: result = kCCHmacAlgMD5 case .SHA1: result = kCCHmacAlgSHA1 case .SHA224: result = kCCHmacAlgSHA224 case .SHA256: result = kCCHmacAlgSHA256 case .SHA384: result = kCCHmacAlgSHA384 case .SHA512: result = kCCHmacAlgSHA512 } return CCHmacAlgorithm(result) } var digestLength: Int { var result: Int32 = 0 switch self { case .MD5: result = CC_MD5_DIGEST_LENGTH case .SHA1: result = CC_SHA1_DIGEST_LENGTH case .SHA224: result = CC_SHA224_DIGEST_LENGTH case .SHA256: result = CC_SHA256_DIGEST_LENGTH case .SHA384: result = CC_SHA384_DIGEST_LENGTH case .SHA512: result = CC_SHA512_DIGEST_LENGTH } return Int(result) } } extension String { func hmac(algorithm: CryptoAlgorithm, key: String) -> String { let str = self.cString(using: String.Encoding.utf8) let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8)) let digestLen = algorithm.digestLength let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen) let keyStr = key.cString(using: String.Encoding.utf8) let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8)) CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result) let digest = stringFromResult(result: result, length: digestLen) result.deallocate(capacity: digestLen) return digest } private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String { let hash = NSMutableString() for i in 0..<length { hash.appendFormat("%02x", result[i]) } return String(hash) } }
Don't forget add #import <CommonCrypto/CommonHMAC.h>
to Header.h
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With