Swift
Installation
Swift Package Manager
Add the dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/zourzouvillys/httpsig", from: "0.1.0"),
]
Then add the targets you need:
.target(
name: "YourApp",
dependencies: [
.product(name: "HTTPSig", package: "httpsig"),
.product(name: "HTTPSigURLSession", package: "httpsig"), // URLRequest signing
.product(name: "HTTPSigAlamofire", package: "httpsig"), // Alamofire interceptor
]
),
Requires Swift 6.0+, macOS 13+ / iOS 16+.
The crypto implementation uses CryptoKit for Ed25519, ECDSA P-256, and HMAC, and the Security framework for RSA-PSS.
Quick Example: Sign a Request
import HTTPSig
import CryptoKit
// Create a key pair (static factory per algorithm)
let privateKey = Curve25519.Signing.PrivateKey()
let kp = KeyPair.ed25519(keyId: "my-key-id", privateKey: privateKey)
let key = kp.signingKey
// Build signature parameters
let params = SignatureParameters(
components: [
.init("@method"),
.init("@path"),
.init("@authority"),
.init("content-type"),
],
keyId: "my-key-id",
created: Int64(Date().timeIntervalSince1970)
)
// Sign a message
let result = try Signer.sign(msg: httpMessage, label: "sig1", params: params, key: key)
// Apply signature headers
request.addValue(
Signer.signatureInputHeader(result),
forHTTPHeaderField: "Signature-Input"
)
request.addValue(
Signer.signatureHeader(result),
forHTTPHeaderField: "Signature"
)
Quick Example: Verify a Signature
import HTTPSig
import CryptoKit
// Set up a KeyProvider
struct MyKeyProvider: KeyProvider {
let publicKey: Curve25519.Signing.PublicKey
func resolve(keyId: String, algorithm: Algorithm?) throws -> (any VerifyingKey)? {
if keyId == "my-key-id" {
return Ed25519VerifyingKey(keyId: keyId, publicKey: publicKey)
}
return nil
}
}
let provider = MyKeyProvider(publicKey: publicKey)
let result = try Verifier.verify(
msg: httpMessage,
provider: provider,
options: VerifyOptions(
requiredComponents: [.init("@method"), .init("@authority")],
maxAge: 300 // 5 minutes
)
)
print("Verified: label=\(result.label), keyId=\(result.keyId)")
HTTP Client Integrations
URLSession
The HTTPSigURLSession module adds a signed() extension to URLRequest:
import HTTPSigURLSession
var request = URLRequest(url: URL(string: "https://example.com/api")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let signed = try request.signed(label: "sig1", params: params, key: signingKey)
let (data, response) = try await URLSession.shared.data(for: signed)
Alamofire
The HTTPSigAlamofire module provides a SigningInterceptor that conforms to Alamofire's RequestInterceptor:
import Alamofire
import HTTPSigAlamofire
let interceptor = SigningInterceptor(key: signingKey, label: "sig1", params: params)
let session = Session(interceptor: interceptor)
let response = await session.request("https://example.com/api").serializingData().response
See the Integrations Guide for more details.
Secure Enclave
On Apple platforms, use SecureEnclaveSigningKey for hardware-backed P-256 keys:
import HTTPSig
import CryptoKit
let seKey = SecureEnclave.P256.Signing.PrivateKey()
let signingKey = SecureEnclaveSigningKey(keyId: "se-key", privateKey: seKey)
// The verifying key is derived automatically from the Secure Enclave key
Notes
Apple CryptoKit uses randomized Ed25519 signing for side-channel resistance. This means Ed25519 signatures produced by Swift will differ from those produced by Go, Java, or other implementations for the same input. Round-trip verification always works correctly.