JWSETKit

1.3.0

A full-featured Swift library for JOSE standards with first-class support for CryptoKit keys, providing JWS, JWT, SD-JWT, and JWE with signing, encryption, and JWK key management.
amosavian/JWSETKit

What's New

JWSETKit 1.3.0

2025-12-24T15:43:48Z
  • feat: JSONWebCertificateChain general availability
  • feat: Resolve cnf key using network
  • feat: HTTP loading for JWKS and x5u certificates
  • feat: Certificate chain verifier (Apple platforms or when X509 trait is set)
  • feat: Import/export X509.Certificate's public key and private key
  • !fix: Symmetric key length minimum for HS algorithms
  • fix: JSONPointer setter handling value when JSONWebFieldEncodable
  • fix: Throw error when JWS/JWE base64url is invalid
  • fix: More appropriate error types in SecKey and JWS/JWE
  • fix: Normalizing key data for JWK thumbprint
  • fix: X509.Certificate key thumbprint fails for SPKI
  • fix: SPKI/PKCS8 parsing in AnyJSONWebKey did not work
  • !chore: Drop iOS 14/macOS 11 support
  • chore: Minor refactor to fix linter and sonar issues
  • tests: Add negative and security input tests

Important

While you can still provide weak shared secret (<256bit) HMAC key for JWS, the algorithm must be declared explicitly.

JWSETKit

A library for working with JSON Web Signature (JWS) and . A modern, type-safe Swift library for JSON Web Token (JWT), JSON Web Signature (JWS), and JSON Web Encryption (JWE) with first-class Apple's CryptoKit support

Swift CodeQL License Release version

Lines of Code Duplicated Lines

Quality Gate Status Technical Debt Maintainability Rating Coverage

Overview

Building secure authentication in Swift? JWSETKit is your complete solution for working with JSON Web Tokens (JWT), JSON Web Signatures (JWS), and JSON Web Encryption (JWE) with native Apple CryptoKit integration.

This module makes it possible to serialize, deserialize, create, and verify JWS/JWT messages.

📖 Table of Contents

🚀 Features

Core Capabilities

JWT (JSON Web Tokens)

  • Create, sign, verify, and decode JWT tokens
  • Support for standard and custom claims
  • Expiration and validation handling

JWS (JSON Web Signature)

  • Digital signatures with multiple algorithms
  • Message authentication codes (MACs)
  • Detached signature support

JWE (JSON Web Encryption)

  • Content encryption with various algorithms
  • Key wrapping and management
  • Compact and JSON serialization

SD-JWT (Selective Disclosure)

  • RFC 9901 compliant selective disclosure
  • Privacy-preserving credential presentations
  • Key binding for holder authentication
  • SD-JWT VC support for Verifiable Credentials

JWK (JSON Web Keys)

  • Key generation and management
  • Key conversion and serialization
  • Support for key sets (JWKS)

Extended Cryptographic Support

CryptoKit Integration

  • JWK encoding/decoding for all CryptoKit key types (P256, P384, P521, Curve25519, RSA)
  • SPKI (SubjectPublicKeyInfo) and PKCS#8 import/export for CryptoKit keys
  • ML-DSA (Dilithium) post-quantum keys with SPKI/PKCS#8 support

secp256k1 (P-256K) Support

  • ES256K signature algorithm for Bitcoin/Ethereum compatibility
  • ECDSA signing and verification
  • Schnorr signature support
  • ECDH key agreement

Getting Started

Swift Package Manager

Add JWSETKit to your Package.swift:

dependencies: [
    .package(url: "https://github.com/amosavian/JWSETKit", from: "1.0.0")
]

Then add to your target:

dependencies: [
    .product(name: "JWSETKit", package: "JWSETKit"),
]

With X509 Support

For X509 certificate support (Swift 6.1+):

dependencies: [
    .package(url: "https://github.com/amosavian/JWSETKit", from: "1.0.0", traits: ["X509"])
]

With P256K Support

For secp256k1 (ES256K) support (Swift 6.1+):

dependencies: [
    .package(url: "https://github.com/amosavian/JWSETKit", from: "1.0.0", traits: ["P256K"])
]

Xcode

  1. File → Add Package Dependencies
  2. Enter: https://github.com/amosavian/JWSETKit
  3. Select version and add to your target

Usage

For detailed usage and API documentation, check the documentation.

Creating and Verifying JWT Signature

import JWSETKit
import CryptoKit

// Create a JWT with claims
let key = SymmetricKey(size: .bits256)
let payload = try JSONWebTokenClaims {
    $0.issuedAt = .init()
    $0.expiry = .init(timeIntervalSinceNow: 3600)
    $0.jwtUUID = .init()
    $0.subject = "user123"
}
let jwt = try JSONWebToken(payload: payload, algorithm: .hmacSHA256, using: key)

// Verify and decode
let decodedJWT = try JSONWebToken(from: jwtString)
try decodedJWT.verifySignature(using: key)
print(decodedJWT.payload.subject) // "user123"

Basic JWT Authentication

// Initialize key
let key = try P256.Signing.PublicKey(pemRepresentation: publicKeyPEM)

// Verify incoming JWT
    
let token = try JSONWebToken(from: request.headers["Authorization"])
try token.verify(using: key, for: "audience-name")

Working with JWS

// Sign arbitrary data with JWS
let payload = "Important message"
let jws = try JSONWebSignaturePlain(
    payload: payload.utf8,
    algorithm: .ecdsaSignatureP256SHA256,
    using: key
)
try print(String(jws))

// Verify JWS signature
let verified = try JSONWebSignaturePlain(from: String(jws))
try verified.verifySignature(using: key)
let message = String(decoding: verified.payload, as: UTF8.self)

Encrypting with JWE

// Encrypt sensitive data
let sensitiveData = Data("Secret information".utf8)
let encryptionKey = JSONWebRSAPrivateKey(keySize: .bits2048) 
let jwe = try JSONWebEncryption(
    content: sensitiveData,
    keyEncryptingAlgorithm: .rsaEncryptionOAEP,
    keyEncryptionKey: encryptionKey.publicKey,
    contentEncryptionAlgorithm: .aesEncryptionGCM128
)
try print(String(jwe))

// Decrypt JWE
let jwe = try JSONWebEncryption(from: jweString)
let decrypted = jwe.decrypt(using: encryptionKey)
let secret = String(decoding: decrypted, as: UTF8.self)

Managing Keys with JWK

// Create CryptoKit key
let privateKey = P256.Signing.PrivateKey()

// Import and Export as JWK data
let jwkJSON = try JSONEncoder().encode(privateKey)
let importedJWK = try JSONDecoder().decode(P256.Signing.PrivateKey.self, from: jwkJSON)

// Import PKCS#8
let importedKey = try P256.Signing.PrivateKey(importing: pkcs8Data, format: .pkcs8)

SD-JWT (Selective Disclosure)

// Issuer: Create SD-JWT with selective claims
let claims = try JSONWebTokenClaims {
    $0.issuer = "https://issuer.example.com"
    $0.subject = "user123"
    $0.giveName = "John"
    $0.familyName = "Doe"
    $0.email = "john@example.com"
}

let sdJWT = try JSONWebSelectiveDisclosureToken(
    claims: claims,
    policy: .standard,  // Standard claims visible, others disclosable
    using: issuerKey
)

// Holder: Create presentation with selected disclosures
let presentation = try sdJWT.presenting(paths: ["/email"])

// Verifier: Validate and access disclosed claims
try presentation.validate()
try presentation.verifySignature(using: issuerPublicKey)
let disclosed = try presentation.disclosedPayload()
print(disclosed.email)  // "john@example.com"

📊 Comparison with Alternatives

Features

JWSETKit jwt-kit JOSESwift Auth0's JWTDecode
JSON Web Signature (JWS)
JWS Multiple Signatures
JWS Unencoded/Detached Payload
JSON Web Token (JWT)
JWT Signature Verification
JWT Expire/NotBefore Validity
JSON Web Encryption (JWE)
SD-JWT (RFC 9901)
Support CommonCrypto Keys
Support CryptoKit Keys

Supported Algorithms

Signature/HMAC

JWSETKit jwt-kit JOSESwift Auth0's JWTDecode
HS256
HS384
HS512
RS256
RS384
RS512
ES256
ES384
ES512
PS256
PS384
PS512
PS512
EdDSA
Ed25519
Ed448
ES256K
ML-DSA-44
ML-DSA-65
ML-DSA-87

Key Encryption

JWSETKit JOSESwift
RSA1_5
RSA-OAEP
RSA-OAEP-256
A128KW
A192KW
A256KW
dir
ECDH-ES
ECDH-ES+A128KW
ECDH-ES+A192KW
ECDH-ES+A256KW
A128GCMKW
A192GCMKW
A256GCMKW
PBES2-HS256+A128KW
PBES2-HS384+A192KW
PBES2-HS512+A256KW
HPKE-0 (P256/AES128)
HPKE-1 (P384/AES256)
HPKE-2 (P521/AES256)
HPKE-3 (X25519/AES256)
HPKE-4 (X25519/ChaCha)
HPKE-5 (X448/AES256)
HPKE-6 (X448/ChaCha)
HPKE-7 (P256/AES256)

Content Encryption

JWSETKit JOSESwift
A128CBC-HS256
A192CBC-HS384
A256CBC-HS512
A128GCM
A192GCM
A256GCM

🏗️ Use Cases

JWSETKit is perfect for:

  • 🔑 API Authentication - Secure REST API authentication with JWT tokens
  • 🌐 OAuth 2.0 / OpenID Connect - Implement modern authentication flows
  • 📱 Mobile App Security - Token-based auth for iOS/macOS apps
  • 🔄 Microservices - Service-to-service authentication
  • 🎫 Session Management - Stateless session tokens
  • 🔐 Data Encryption - Protect sensitive data with JWE
  • 🪪 Verifiable Credentials - Privacy-preserving identity with SD-JWT

📚 Documentation

Browse our comprehensive guides:

🤝 Contributing

We welcome contributions!

How to Contribute

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development

# Clone the repository
git clone https://github.com/amosavian/JWSETKit.git

# Run tests
swift test

# Build the project
swift build

🌟 Support

📄 License

JWSETKit is released under the MIT License. See LICENSE for details.

🙏 Acknowledgments

This library implements the following JOSE standards:

  • RFC 7515 - JSON Web Signature (JWS)
  • RFC 7516 - JSON Web Encryption (JWE)
  • RFC 7517 - JSON Web Key (JWK)
  • RFC 7518 - JSON Web Algorithms (JWA)
  • RFC 7519 - JSON Web Token (JWT)
  • RFC 7520 - Examples of Protecting Content Using JSON Object Signing and Encryption (JOSE)
  • RFC 7797 - JSON Web Signature (JWS) Unencoded Payload Option
  • RFC 7800 - Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)
  • RFC 9864 - Fully-Specified Algorithms for JOSE and COSE
  • RFC 9901 - SD-JWT: Selective Disclosure for JWTs
  • draft-ietf-jose-hpke-encrypt - Use of Hybrid Public Key Encryption (HPKE) with JSON Object Signing and Encryption (JOSE)
  • draft-ietf-cose-dilithium - ML-DSA for JOSE and COSE
  • OIDC Core - OpenID Connect Core 1.0 incorporating errata set 2

Built with ❤️ using Swift

Star on GitHub

Description

  • Swift Tools 6.1.0
View More Packages from this Author

Dependencies

Last updated: Mon Feb 02 2026 01:31:35 GMT-1000 (Hawaii-Aleutian Standard Time)