使用 Swift,如何使用 SHA1 创建 OpenSSL HMAC 摘要,然后使用严格的 encode64 进行编码

Using Swift, how can I create an OpenSSL HMAC digest using SHA1 and then encode with strict encode64

我需要使用 SHA1 创建 OpenSSL HMAC 摘要的 Base64 严格编码表示。我有 Ruby 中的代码,但我需要 Swift 中的类似代码。有人有那么简单吗?

Ruby中的代码是:

digest = OpenSSL::Digest.new('sha1')
hmac_digest = OpenSSL::HMAC.digest(digest, secret_key, canonical_string)
Base64.strict_encode64(hmac_digest)

正如您在上面看到的,我的输入是 2 个字符串(secret_keycanonical_string),我首先创建摘要然后对其进行编码。

那么,Swift 中对相同输入给出相同结果的正确代码是什么?

我创建了一个用于导入的桥接头 CommonCrypto.h

然后我用以下函数扩展了字符串:

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!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)

    let hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength())))

    let hmacBase64 = hmacData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding76CharacterLineLength)

    return String(hmacBase64)
 }
}