kingpin-apps/swift-cose
This project is a Swift implementation of the IETF CBOR Encoded Message Syntax (COSE). COSE has reached RFC status and is now available at RFC 8152.
Platform support
| Platform | Status | |---|---| | iOS / macOS / watchOS / tvOS / visionOS | ✓ | | Linux | ✓ | | Android | ✓ | | WebAssembly (WASI) | ✗ — blocked upstream |
WASM is blocked by apple/swift-crypto's _CryptoExtras module (pulled in transitively via swift-certificates/X509): Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift references a ThreadOpsSystem typealias that has no WASI implementation. Upstream itself is not green for WASM — see the swift-crypto build matrix. We'll revisit when upstream lands WASI support.
Usage
To add SwiftCOSE as dependency to your Xcode project, select File > Swift Packages > Add Package Dependency, enter its repository URL: https://github.com/Kingpin-Apps/swift-cose.git and import SwiftCOSE.
``swift dependencies: [ .package(url: "https://github.com/Kingpin-Apps/swift-cose.git", from: "0.0.1") ] ``
Then, to use it in your source code, add:
import SwiftCOSEWhat is COSE ?
CBOR Encoded Message Syntax (COSE) is a data format for concise representation of small messages RFC 8152. COSE is optimized for low power devices. The messages can be encrypted, MAC'ed and signed. There are 6 different types of COSE messages:
- Encrypt0: An encrypted COSE message with a single recipient. The payload and AAD are protected by a shared CEK (Content Encryption Keys)
- Encrypt: An encrypted COSE message can have multiple recipients. For each recipient the CEK is encrypted with a KEK (Key Encryption Key) - using AES key wrap - and added to the message.
- MAC0: An authenticated COSE message with one recipient.
- MAC: An authenticated COSE message that can have multiple recipients. For each recipient, the authentication key is encrypted with a KEK and added to the message.
- Sign1: A signed COSE message with a single signature.
- Sign: A COSE message that has been signed by multiple entities (each signature is carried in a COSE signature structure, added to the message).
A basic COSE message consists of 2 information buckets and the payload:
- Protected header: This message field contains information that needs to be protected. This information is taken into account during the encryption, calculation of the MAC or the signature.
- Unprotected header: The information contained in the unprotected header is not protected by the cryptographic algorithms.
- Payload: Contains the payload of the message, protected (mac'ed, signed or encrypted) by the cryptographic algorithms.
Additionally, based on the message type, other message fields can be added:
- MAC or signature (for MAC0 or Sign1 messages)
- COSE recipients or COSE signatures (for MAC, Encrypt, and Sign messages)
Examples
Encoding
import SwiftCOSE
// Create a COSE Encrypt0 Message
let msg = Enc0Message(
phdr: [
Algorithm(): A128GCM(),
IV(): Data([0x01, 0x02, 0x03, 0x04])
],
uhdr: [
KID(): Data("test.guy@example.com".utf8)
],
payload: Data("A secret message".utf8)
)
// Create a COSE Symmetric Key
let coseKey = SymmetricKey.generateKey(keyLength: 32)
msg.key = coseKey
// Performs encryption and CBOR serialization
msg.encode()Decoding
import SwiftCOSE
// message bytes (CBOR encoded)
let msg = Data([0xd8, 0x3d, 0x85, 0x01, 0x01, 0xa0, 0x01, 0x02, 0x03, 0x04, 0x58, 0x14, 0x54, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65])
let coseMsg = Enc0Message.decode(from: msg)
// Create a COSE Symmetric Key
let coseKey = SymmetricKey.generateKey(keyLength: 32)
msg.key = coseKey
msg.decrypt()Package Metadata
Repository: kingpin-apps/swift-cose
Default branch: main
README: README.md