Skip to content
Mobile
Skill

/cryptokit

Use Apple CryptoKit for Swift cryptographic primitives. Use when hashing with SHA-2 or SHA-3, generating HMACs, encrypting with AES-GCM or ChaChaPoly, signing with P256/P384/P521/Curve25519 or ML-DSA keys, performing ECDH, HPKE, ML-KEM, or X-Wing key exchange, using Secure

From plugin
swift-ios-skills
1.3k86 skills1 MCP

Claude Code

$ npx -y skills add dpearson2699/swift-ios-skills --skill cryptokit --agent claude-code

SKILL.md

cryptokit.SKILL.md
name: cryptokit
description: "Use Apple CryptoKit for Swift cryptographic primitives. Use when hashing with SHA-2 or SHA-3, generating HMACs, encrypting with AES-GCM or ChaChaPoly, signing with P256/P384/P521/Curve25519 or ML-DSA keys, performing ECDH, HPKE, ML-KEM, or X-Wing key exchange, using Secure Enclave CryptoKit keys, or migrating CommonCrypto code to CryptoKit."

CryptoKit

Apple CryptoKit provides a Swift-native API for cryptographic operations: hashing, message authentication, symmetric encryption, public-key signing, key agreement, HPKE, quantum-secure key encapsulation/signing, and Secure Enclave-backed keys. Most core primitives are available on iOS 13+; check availability for HPKE (iOS 17+) and SHA-3 / post-quantum APIs (iOS 26+). Prefer CryptoKit over CommonCrypto or raw Security framework APIs for new cryptographic primitive code targeting Swift 6.3+.

Contents

  • [Hashing](#hashing)
  • [HMAC](#hmac)
  • [Symmetric Encryption](#symmetric-encryption)
  • [Public-Key Signing](#public-key-signing)
  • [Key Agreement](#key-agreement)
  • [HPKE](#hpke)
  • [Post-Quantum CryptoKit](#post-quantum-cryptokit)
  • [Secure Enclave](#secure-enclave)
  • [Common Mistakes](#common-mistakes)
  • [Review Checklist](#review-checklist)
  • [References](#references)

Hashing

Use SHA256/SHA384/SHA512 on iOS 13+; SHA3_256/SHA3_384/SHA3_512 require iOS 26+. All conform to `HashFunction`.

One-shot hashing

import CryptoKit

let data = Data("Hello, world!".utf8)
let digest = SHA256.hash(data: data)
let hex = digest.compactMap { String(format: "%02x", $0) }.joined()

SHA-3 availability

Use SHA-3 only behind an availability check unless the deployment target is iOS 26+:

if #available(iOS 26.0, *) {
    let digest = SHA3_256.hash(data: data)
}

Incremental hashing

For large data or streaming input, hash incrementally:

var hasher = SHA256()
hasher.update(data: chunk1)
hasher.update(data: chunk2)
let digest = hasher.finalize()

Digest comparison

Compare CryptoKit digest values directly. Do not convert digests to strings or arrays for security-sensitive equality checks.

let expected = SHA256.hash(data: reference)
let actual = SHA256.hash(data: received)
if expected == actual {
    // Data integrity verified
}

HMAC

Use HMAC when a protocol requires keyed message authentication; verify with `isValidAuthenticationCode` rather than comparing serialized values yourself.

Computing an authentication code

let key = SymmetricKey(size: .bits256)
let data = Data("message".utf8)

let mac = HMAC<SHA256>.authenticationCode(for: data, using: key)

Verifying an authentication code

let isValid = HMAC<SHA256>.isValidAuthenticationCode(
    mac, authenticating: data, using: key
)

Incremental HMAC

var hmac = HMAC<SHA256>(key: key)
hmac.update(data: chunk1)
hmac.update(data: chunk2)
let mac = hmac.finalize()

Symmetric Encryption

CryptoKit provides two authenticated encryption ciphers: AES-GCM and ChaChaPoly. Both produce a sealed box containing the nonce, ciphertext, and authentication tag.

AES-GCM

The default choice for symmetric encryption. Hardware-accelerated on Apple silicon.

let key = SymmetricKey(size: .bits256)
let plaintext = Data("Secret message".utf8)

// Encrypt
let sealedBox = try AES.GCM.seal(plaintext, using: key)
let ciphertext = sealedBox.combined!  // nonce + ciphertext + tag

// Decrypt
let box = try AES.GCM.SealedBox(combined: ciphertext)
let decrypted = try AES.GCM.open(box, using: key)

ChaChaPoly

Use ChaChaPoly when AES hardware acceleration is unavailable or when interoperating with protocols that require ChaCha20-Poly1305 (e.g., TLS, WireGuard).

let sealedBox = try ChaChaPoly.seal(plaintext, using: key)
let combined = sealedBox.combined  // Always non-optional for ChaChaPoly

let box = try ChaChaPoly.SealedBox(combined: combined)
let decrypted = try ChaChaPoly.open(box, using: key)

Authenticated data

Both ciphers support additional authenticated data (AAD). The AAD is authenticated but not encrypted -- useful for metadata that must remain in the clear but be tamper-proof.

let header = Data("v1".utf8)
let sealedBox = try AES.GCM.seal(
    plaintext, using: key, authenticating: header
)
let decrypted = try AES.GCM.open(
    sealedBox, using: key, authenticating: header
)

Use `.bits256` as the default `SymmetricKey` size for AES-256-GCM or ChaChaPoly. To create a key from existing data:

let key = SymmetricKey(data: existingKeyData)

Public-Key Signing

CryptoKit supports ECDSA signing with NIST curves and Ed25519 via Curve25519.

NIST curves: P256, P384, P521

let signingKey = P256.Signing.PrivateKey()
let publicKey = signingKey.publicKey

// Sign
let signature = try signingKey.signature(for: data)

// Verify
let isValid = publicKey.isValidSignature(signature, for: data)

P384 and P521 use the same API -- substitute the curve name.

NIST keys support DER, PEM, X9.63, and raw representations. See [references/cryptokit-patterns.md](references/cryptokit-patterns.md) for serialization examples.

Curve25519 / Ed25519

let signingKey = Curve25519.Signing.PrivateKey()
let publicKey = signingKey.publicKey

// Sign
let signature = try signingKey.signature(for: data)

// Verify
let isValid = publicKey.isValidSignature(signature, for: data)

Curve25519 keys use `rawRepresentation` only (no DER/PEM/X9.63).

Choosing a curve

| Curve | Signature Scheme | Key Size | Typical Use | |---|---|---|---| | P256 | ECDSA | 256-bit | General purpose; Secure Enclave support | | P384 | ECDSA | 384-bit | Higher security requirements | | P521 | ECDSA | 521-bit | Maximum NIST security level | | Curve25519 | Ed25519 | 256-bit | Fast; simple API; no Secure Enclave |

Use P256 by default. Use Curve25519 when interoperating with Ed25519-based protocols.

Key Agreement

Key agreem

Read more
@dpearson2699
Ships withswift-ios-skills

86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.

1.3k86 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.3k
Star history of dpearson2699/swift-ios-skills on GitHub, a chart by star-history.com

Other skills on swift-ios-skills.

alarmkit

alarmkit

Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple…

app-clips

app-clips

Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store…

More skills from other plugins.

deep-code-review

deep-code-review

In-depth design-focused code review - understands codebase context before evaluating PR changes, posts structured feedback to…

expo1d53k
@expo@expoInstall Skill
modlens

modlens

Plug-in vision for text-only models. Hard rule: when a file path or URL with an image extension (.png, .jpg, .jpeg, .webp, .gif,…

modlens2w4.6k
@liustack@liustackInstall Skill
appllama-app-design-skill

appllama-app-design-sk…

Build native-feeling, benchmark-quality mobile app screens (Expo / React Native). Use when designing or implementing any mobile…

appllama2mo3.9k
@appllama@appllamaInstall Skill

Questions about cryptokit.

Which coding agents can use cryptokit?
cryptokit installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.