What it is
Apple's open-source implementation of the CryptoKit API, providing hashing, HMAC, symmetric and public-key cryptography across Apple platforms and Linux.
The API is deliberately narrow and hard to misuse: modern algorithms only, authenticated encryption by default, and no way to select a broken cipher.
Installation
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.8.0")Getting started
The smallest useful thing you can do with it, and what each part means.
swift
import Crypto
let digest = SHA256.hash(data: Data(payload.utf8))
let hex = digest.compactMap { String(format: "%02x", $0) }.joined()
// Verify a webhook signature — constant-time comparison.
let key = SymmetricKey(data: secret)
let valid = HMAC<SHA256>.isValidAuthenticationCode(
receivedSignature, authenticating: body, using: key
)
// AES-GCM: encryption and authentication together.
let sealed = try AES.GCM.seal(plaintext, using: key)
let combined = sealed.combined! // nonce + ciphertext + tag
let box = try AES.GCM.SealedBox(combined: combined)
let decrypted = try AES.GCM.open(box, using: key)Advanced usage
Where the library earns its place over a simpler alternative.
swift
// Ephemeral key agreement (X25519).
let privateKey = Curve25519.KeyAgreement.PrivateKey()
let shared = try privateKey.sharedSecretFromKeyAgreement(
with: peerPublicKey
)
// Never use the raw shared secret as a key — derive one.
let symmetricKey = shared.hkdfDerivedSymmetricKey(
using: SHA256.self,
salt: salt,
sharedInfo: Data("app-v1".utf8),
outputByteCount: 32
)
// Signing (Ed25519).
let signingKey = Curve25519.Signing.PrivateKey()
let signature = try signingKey.signature(for: message)
let ok = signingKey.publicKey.isValidSignature(signature, for: message)Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- CryptoKitError.authenticationFailure
- The ciphertext or tag was altered, or the wrong key was used. This is the integrity check working — do not ignore it.
- incorrectKeySize
- The key length does not match the algorithm. Derive a correctly sized key with HKDF.
Best practices
- Never compare secrets with ==; use the constant-time verification functions.
- Derive keys with HKDF rather than using raw shared secrets or passwords directly.
- Store keys in the Keychain, not in UserDefaults or a file.
- Prefer AES.GCM or ChaChaPoly — both authenticate as well as encrypt.
Background
Why it exists, and what it was reacting to.
CryptoKit is Apple-only. Swift Crypto reimplements the same API on top of BoringSSL so server-side Swift on Linux can use identical code, which matters for shared client and server logic.
