Swift package providing OpenSSL cryptographic functionality with modern Swift APIs. Uses Swift's C interoperability with OpenSSL.
- Provide modern Swift bindings for OpenSSL cryptographic operations
- Offer a familiar API design inspired by Swift Crypto
- Expose libcrypto and libssl bindings for full control of the implementation
- Ensure availability for Linux and Apple platform ecosystems
- Maintain automatic updates for Swift and OpenSSL versions
This package uses Swift Package Manager. To add it to your project:
- Go to
File > Add Packages... - Enter the package URL:
https://github.com/21-DOT-DEV/swift-openssl - Select the desired version
Add the following to your Package.swift file:
.package(url: "https://github.com/21-DOT-DEV/swift-openssl.git", from: "0.1.0"),Warning
This package is pre-1.0 (SemVer major version zero). The public API should not be considered stable and may change with any release. Pin a version using exact: to avoid unexpected breaking changes.
Then, include OpenSSL as a dependency in your target:
.target(name: "<target>", dependencies: [
.product(name: "OpenSSL", package: "swift-openssl")
]),Caution
This package has not yet implemented cryptographic test vectors. Do not use in production until proper verification is in place.
import OpenSSL
// Hash data
let data = "Hello, World!".data(using: .utf8)!
let digest = SHA256.hash(data: data)
print(digest.hexString)
// Hash string directly
let stringDigest = SHA256.hash(string: "Hello, World!")
print(stringDigest.hexString)import OpenSSL
// Encode data as base64url (useful for JWT)
let data = "Hello, World!".data(using: .utf8)!
let encoded = Base64URL.encode(data)
print(encoded)
// Decode base64url string
if let decoded = Base64URL.decode(encoded) {
print(String(data: decoded, encoding: .utf8)!)
}import OpenSSL
let privateKeyPEM = """
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
"""
// Parse PEM-encoded keys
let privateKey = try RSA.PrivateKey(pemRepresentation: privateKeyPEM)
print(privateKey.pemData)Note
RSA signing and verification require the OpenSSL provider layer, which is not yet included. Key parsing is functional.
import OpenSSL
// Get the OpenSSL version string
print(SSL.versionString)- Swift 6.1+
- macOS 13+, iOS 16+, tvOS 16+, watchOS 9+, visionOS 1+
OpenSSL is vendored via git subtree. Update procedure depends on the release scale:
# 1. Bump the subtree to a new tag (updates subtree.yaml + commits Vendor with git-subtree-* trailers)
swift package --build-path .build/subtree \
--allow-writing-to-package-directory \
--allow-network-connections all \
subtree update openssl --ref openssl-3.6.2
# 2. Re-extract (--force overwrites previously-extracted sources)
swift package --build-path .build/subtree \
--allow-writing-to-package-directory \
subtree extract --name openssl --force
# 3. Verify
swift build && swift testIf step 3 is green, you're done. The Configure-generated files already under Sources/libcrypto/ survive because we skip --clean.
Patch releases can still change Configure .h.in templates (e.g., new OSSL_CMP_PKISTATUS_* constants in 3.6.2). If step 3 above fails with missing identifiers, run the full Configure dance:
# Regenerate Configure outputs
cd Vendor/openssl
./Configure darwin64-arm64-cc no-asm no-shared no-apps no-docs no-tests \
no-rc5 no-rc2 no-idea no-bf no-cast no-seed no-camellia \
no-mdc2 no-whirlpool no-md2 no-md4 \
no-sm2 no-sm3 no-sm4 no-aria no-gost no-blake2 \
no-lms no-ml-dsa no-ml-kem no-slh-dsa \
no-ec_nistp_64_gcc_128 no-padlockeng
make build_all_generated
cd ../..
# Re-extract to pick up regenerated .h and generated .c files
swift package --build-path .build/subtree \
--allow-writing-to-package-directory \
subtree extract --name openssl --force
# Clean Vendor (IMPORTANT — generated files must NOT be committed to Vendor/)
( cd Vendor/openssl && make distclean )
# Verify
swift build && swift testConfigure-generated files (live under Sources/libcrypto/, NOT in upstream Vendor/openssl/):
include/openssl/configuration.h— build configuration +OPENSSL_NO_*definesinclude/openssl/*.hfrom.h.intemplates —cmp.h,ssl.h,asn1.h,bio.h,x509.h, etc.internal_include/crypto/buildinf.h— build info (compiler, date, platform)providers/providers/fips/include/fips/fipsindicator.h— FIPS indicator macros- Provider
.cfiles generated from.c.intemplates
Disabled algorithms:
| Category | Algorithms | Rationale |
|---|---|---|
| Legacy ciphers | RC5, RC2, IDEA, BF, CAST, SEED, Camellia | Deprecated, rarely used |
| Legacy hashes | MDC2, Whirlpool, MD2, MD4, Blake2 | Deprecated or specialized |
| Regional standards | SM2, SM3, SM4, ARIA, GOST | Chinese/Korean/Russian standards |
| Post-quantum | LMS, ML-DSA, ML-KEM, SLH-DSA | Experimental, increases binary size |
| Platform-specific | ec-nistp-64-gcc-128, padlockeng | Requires specific compiler/hardware |
Important: Always run make distclean after extraction. Generated files must NOT be committed to Vendor/openssl/ as they will conflict with subtree operations.
Sources/
├── OpenSSL/ # Swift wrapper API
├── libcrypto/ # OpenSSL crypto library (extracted + generated)
│ ├── crypto/ # Core crypto sources
│ ├── include/ # Public headers (openssl/*.h)
│ ├── internal_include/ # Internal headers (crypto/*.h, internal/*.h)
│ └── providers/ # Provider headers
└── libssl/ # OpenSSL SSL/TLS library (extracted)
├── src/ # SSL sources
└── include/ # SSL headers
For information on reporting security vulnerabilities, see SECURITY.md.
Contributions are welcome. Please read the 21-DOT-DEV contributing guidelines for branching and commit guidelines. For AI-assisted development guidance, see AGENTS.md.
This project is released under the MIT License. See LICENSE for details.
OpenSSL is licensed under the Apache License 2.0.