Search code examples
iosswiftxcode6

Implementing HMAC and SHA1 encryption in swift


I am relatively new to Swift and i'm stuck encrypting using HMAC and SHA1. I Found the following answer https://stackoverflow.com/a/24411522/4188344 but i can't work out how to implement this properly. Any help would be amazing.


Solution

  • Problem solved! First off i wasn't using the string function properly... I ended up with this:

        let hmacResult:String = "myStringToHMAC".hmac(HMACAlgorithm.SHA1, key: "myKey")
    

    Then I had forgotten I needed to base64 encode the hmac result. So i modified the string function linked in my question to...

    enum HMACAlgorithm {
        case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
    
        func toCCHmacAlgorithm() -> 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)
        }
    
        func digestLength() -> Int {
            var result: CInt = 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: HMACAlgorithm, key: String) -> String {
            let cKey = key.cStringUsingEncoding(NSUTF8StringEncoding)
            let cData = self.cStringUsingEncoding(NSUTF8StringEncoding)
            var result = [CUnsignedChar](count: Int(algorithm.digestLength()), repeatedValue: 0)
            CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, strlen(cKey!), cData!, strlen(cData!), &result)
            var hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength())))
            var hmacBase64 = hmacData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding76CharacterLineLength)
            return String(hmacBase64)
        }
    }
    

    This is giving me the correct result of

    lGCtbW+DNHFraNoxPGK3trgM/98=