# A practical guide to swift-crypto: CryptoKit-style APIs on Linux, Windows, and Apple platforms

**URL:** <https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445>\
**Category:** Using Swift\
**Created:** [November 4, 2026, 6:35am UTC](https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445 "2026-11-04T06:35:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dheerendra](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dheerendra/32/47241_2.png) [@dheerendra](https://forums.swift.org/u/dheerendra)\
**Post date:** [November 4, 2026, 6:35am UTC](https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445/1 "2026-11-04T06:35:35Z")

</div>

Hi everyone! I've been using [swift-crypto](https://github.com/apple/swift-crypto) in server-side and cross-platform projects, so here's a quick overview with patterns I've found useful.

### What is swift-crypto?

swift-crypto is Apple's open-source version of the **CryptoKit** API.

- **On Apple platforms** , `import Crypto` re-exports the system CryptoKit, so you get the OS implementation.
- **On Linux, Windows, and Android** , it uses a vendored copy of BoringSSL behind the same API.

This means one codebase with no `#if canImport(CryptoKit)` branches for most use cases.

### Installation

```swift
.package(url: "https://github.com/apple/swift-crypto.git", "3.0.0"..<"5.0.0"),
// target:
.product(name: "Crypto", package: "swift-crypto"),

```

### 1. Hashing

```swift
import Crypto

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

```

`Insecure.MD5` and `Insecure.SHA1` exist only for legacy interop. The namespace is a deliberate warning.

### 2. HMAC (e.g. webhook signature verification)

```swift
let key = SymmetricKey(data: Data(secret.utf8))
let isValid = HMAC<SHA256>.isValidAuthenticationCode(
    receivedMAC, authenticating: body, using: key
)

```

Use `isValidAuthenticationCode` rather than comparing bytes with `==`, because it compares in constant time.

### 3. Authenticated encryption (AES-GCM / ChaChaPoly)

```swift
let key = SymmetricKey(size: .bits256)

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

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

```

`seal` generates a random nonce for you. If you supply your own, **never reuse a nonce with the same key**. `ChaChaPoly` has an identical API and is a good choice on hardware without AES acceleration.

### 4. Signatures (Curve25519 / P256)

```swift
let signingKey = Curve25519.Signing.PrivateKey()
let signature = try signingKey.signature(for: message)
let ok = signingKey.publicKey.isValidSignature(signature, for: message)

```

P256/P384/P521 keys support `pemRepresentation` and `derRepresentation`, which helps when interoperating with OpenSSL, JWTs (ES256), or other languages.

### 5. Key agreement + HKDF

```swift
let alice = P256.KeyAgreement.PrivateKey()
let bob = P256.KeyAgreement.PrivateKey()

let shared = try alice.sharedSecretFromKeyAgreement(with: bob.publicKey)
let sessionKey = shared.hkdfDerivedSymmetricKey(
    using: SHA256.self,
    salt: salt,
    sharedInfo: Data("my-app v1 session".utf8),
    outputByteCount: 32
)

```

Never use the raw `SharedSecret` directly as a key. Always run it through HKDF.

### `_CryptoExtras`

The package also ships `_CryptoExtras`, which has APIs that aren't in CryptoKit, such as RSA (for legacy interop) and AES-CBC/CTR. The underscore means the API may change, so pin versions carefully.

### Tips

- Keep keys out of source code. Load them from the Keychain, a secrets manager, or environment variables.
- Use `SymmetricKey(size:)` for random keys rather than building your own from `Data`.
- Prefer the high-level AEAD APIs over hand-rolled encrypt-then-MAC.
- Test on both macOS and Linux in CI. The API is the same, but the backends differ.

Happy to hear how others are using swift-crypto, especially on server-side or Android. Feedback and corrections are welcome!

---

<div class="post-metadata">

**Author:** ![ptoffy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ptoffy/32/44481_2.png) [@ptoffy](https://forums.swift.org/u/ptoffy)\
**Post date:** [November 4, 2026, 10:08am UTC](https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445/2 "2026-11-04T10:08:50Z")

</div>

> [@dheerendra](#):
>
> `.package(url: "https://github.com/apple/swift-crypto.git", "3.0.0"..<"5.0.0"),`

FYI we're at [5.1.1](https://github.com/apple/swift-crypto/releases/tag/5.1.1) now so you should be able to do `"3.0.0"..<"6.0.0"`

---

<div class="post-metadata">

**Author:** ![dheerendra](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dheerendra/32/47241_2.png) [@dheerendra](https://forums.swift.org/u/dheerendra)\
**Post date:** [November 4, 2026, 10:17am UTC](https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445/3 "2026-11-04T10:17:31Z")

</div>

> [@ptoffy](#):
>
> FYI we're at [5.1.1](https://github.com/apple/swift-crypto/releases/tag/5.1.1) now so you should be able to do `"3.0.0"..<"6.0.0"`

Thanks for the heads-up! I’ve updated the installation snippet to `"3.0.0"..<"6.0.0"` so it picks up the 5.x releases.

---

<div class="post-metadata">

**Author:** ![craigwrong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/craigwrong/32/34133_2.png) [@craigwrong](https://forums.swift.org/u/craigwrong)\
**Post date:** [November 4, 2026, 10:56am UTC](https://forums.swift.org/t/a-practical-guide-to-swift-crypto-cryptokit-style-apis-on-linux-windows-and-apple-platforms/90445/4 "2026-11-04T10:56:29Z")

</div>

Thanks for the practical guide!

We rely heavily on multiplatform Swift Crypto to build [Swift Bitcoin](https://github.com/swift-bitcoin/swift-bitcoin). We combined it with a safe wrapper of the [secp256k1](https://github.com/swift-bitcoin/secp256k1) Elliptic Curve library and supplemented it to offer a BitcoinCrypto product.

All in all we use the following cryptographic/hashing functions from the Crypto package:

- HMAC-SHA512
- ChaCha20-Poly1305
- HKDF-SHA256

Additional ones from secp256k1:

- ECDSA
- Schnorr Signatures (BIP340)
- MuSig2 (BIP327)
- PBKDF2
- ElligatorSwift
- ECDH

And while we don't like rolling our own crypto we had to fill in the blanks with these:

- RIPEMD-160
- SipHash-2-4
- Double-SHA256 (SHA256d)

One thing we had to adapt Swift Crypto for is getting span support and more efficient representations of hashes/signatures like InlineArray or UInt256.

Anyway, that's how we leverage it and we hope that the library keeps growing so we can use it even more!
