The best (IMO, but I’m biased :-) examples of using CommonCrypto for AES-ECB and AES-CBC are in the CryptoCompatibility sample code.
Note These are in Objective-C, and converting them to Swift is a bit tricky. Pasted in below is an example of such a conversion.
For an example of encrypting with AES-GCM:
Get the Performing Common Cryptographic Operations playground.
Switch to the Encrypting Data page.
Change
ChaChaPoly
to AES.GCM
.Add an exclamation mark to the end of line 26 (the
combined
property on AES.GCM
returns an optional value [1] whereas the same property on ChaChaPoly
is non-optional).
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
[1] You get back
nil
if the
nonce
has the wrong size.
import Foundation
import CommonCrypto
final class QCCAESCryptor: Operation {
init(plainText: Data, key: Data) {
self.op = CCOperation(kCCEncrypt)
self.input = plainText
self.key = key
super.init()
}
init(cypherText: Data, key: Data) {
self.op = CCOperation(kCCDecrypt)
self.input = cypherText
self.key = key
super.init()
}
private let op: CCOperation
let input: Data
let key: Data
var iv: Data? = nil
private(set) var result: Result<Data, Error>? = nil
private override init() {
fatalError()
}
override func main() {
self.result = Result<Data, Error> {
guard
self.input.count.isMultiple(of: kCCBlockSizeAES128),
[kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256].contains(self.key.count),
self.iv.flatMap({ $0.count == kCCBlockSizeAES128 }) ?? true
else {
throw NSError(domain: Self.errorDomain, code: kCCParamError, userInfo: nil)
}
var result = Data(count: self.input.count)
let ecbMode = self.iv == nil
let effectiveIV = self.iv ?? Data(count: kCCBlockSizeAES128)
var resultCount = 0
let err = self.input.withUnsafeBytes { inputBuf in
self.key.withUnsafeBytes { keyBuf in
effectiveIV.withUnsafeBytes { ivBuf in
result.withUnsafeMutableBytes { resultBuf in
CCCrypt(
self.op,
CCAlgorithm(kCCAlgorithmAES128),
CCOptions(ecbMode ? kCCOptionECBMode : 0),
keyBuf.baseAddress!,
keyBuf.count,
ecbMode ? nil : ivBuf.baseAddress!,
inputBuf.baseAddress!,
inputBuf.count,
resultBuf.baseAddress!,
resultBuf.count,
&resultCount
)
}
}
}
}
guard err == kCCSuccess else {
throw NSError(domain: Self.errorDomain, code: kCCParamError, userInfo: nil)
}
result.count = resultCount
return result
}
}
static let errorDomain = "QCCAESCryptorErrorDomain"
}