Last active
April 12, 2022 12:40
-
-
Save laevandus/8939df8acaa3d883829d509e8f408a9f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CommonCrypto | |
extension Data { | |
enum Algorithm { | |
case md5 | |
case sha1 | |
case sha224 | |
case sha256 | |
case sha384 | |
case sha512 | |
var digestLength: Int { | |
switch self { | |
case .md5: return Int(CC_MD5_DIGEST_LENGTH) | |
case .sha1: return Int(CC_SHA1_DIGEST_LENGTH) | |
case .sha224: return Int(CC_SHA224_DIGEST_LENGTH) | |
case .sha256: return Int(CC_SHA256_DIGEST_LENGTH) | |
case .sha384: return Int(CC_SHA384_DIGEST_LENGTH) | |
case .sha512: return Int(CC_SHA512_DIGEST_LENGTH) | |
} | |
} | |
} | |
} | |
extension Data.Algorithm: RawRepresentable { | |
typealias RawValue = Int | |
init?(rawValue: Int) { | |
switch rawValue { | |
case kCCHmacAlgMD5: self = .md5 | |
case kCCHmacAlgSHA1: self = .sha1 | |
case kCCHmacAlgSHA224: self = .sha224 | |
case kCCHmacAlgSHA256: self = .sha256 | |
case kCCHmacAlgSHA384: self = .sha384 | |
case kCCHmacAlgSHA512: self = .sha512 | |
default: return nil | |
} | |
} | |
var rawValue: Int { | |
switch self { | |
case .md5: return kCCHmacAlgMD5 | |
case .sha1: return kCCHmacAlgSHA1 | |
case .sha224: return kCCHmacAlgSHA224 | |
case .sha256: return kCCHmacAlgSHA256 | |
case .sha384: return kCCHmacAlgSHA384 | |
case .sha512: return kCCHmacAlgSHA512 | |
} | |
} | |
} | |
extension Data { | |
func authenticationCode(for algorithm: Algorithm, secretKey: String = "") -> Data { | |
guard let secretKeyData = secretKey.data(using: .utf8) else { fatalError() } | |
return authenticationCode(for: algorithm, secretKey: secretKeyData) | |
} | |
func authenticationCode(for algorithm: Algorithm, secretKey: Data) -> Data { | |
let hashBytes = UnsafeMutablePointer<UInt8>.allocate(capacity: algorithm.digestLength) | |
defer { hashBytes.deallocate() } | |
withUnsafeBytes { (bytes) -> Void in | |
secretKey.withUnsafeBytes { (secretKeyBytes) -> Void in | |
CCHmac(CCHmacAlgorithm(algorithm.rawValue), secretKeyBytes, secretKey.count, bytes, count, hashBytes) | |
} | |
} | |
return Data(bytes: hashBytes, count: algorithm.digestLength) | |
} | |
} |
Hi, since I wrote this Apple released CryptoKit and that framework contains implementations for these as well. I would suggest using that instead. Example, SHA512
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is very helpful, but XCode 13 is warning about a deprecation:
Any chance to update this please?