CBOR and ASN.1 in Swift: Complete Guide to Binary Serialization

Published on ยท 34 min

Wlad
Wlad
Founder & CEO

Introduction

When talking about data serialization, JSON largely dominates the web and mobile ecosystem. Yet, in critical domains like IoT, strong authentication (WebAuthn/FIDO2), digital certificates, or mobile identity (ISO 18013-5), two binary formats reign supreme: CBOR (Concise Binary Object Representation) and ASN.1 (Abstract Syntax Notation One).

This article guides you through these two essential standards for any Swift developer working on secure projects. You'll discover their structure, their differences, and most importantly how to implement them efficiently with the tools available in 2026.

๐ŸŽฏ What is CBOR?

CBOR (Concise Binary Object Representation), defined in RFC 8949, is a binary serialization format designed to be compact, fast to parse, and extensible without version negotiation.

Design Goals

CBOR was created with precise goals that distinguish it from other formats:

Code compactness: A CBOR encoder/decoder can be implemented in a few hundred lines of code, ideal for microcontrollers. Message compactness: Encoded data is significantly smaller than JSON. Self-description: Unlike Protocol Buffers, no schema is required to decode data. Extensibility: The tag system allows adding semantic types without breaking compatibility.

Main Use Cases

CBOR has become the reference format in several critical domains:

IoT and embedded systems: CoAP (Constrained Application Protocol) uses CBOR as its default payload format. WebAuthn and FIDO2: Security key attestations and assertions are encoded in CBOR. COSE (CBOR Object Signing and Encryption): Cryptographic standard defined in RFC 9052 and RFC 9053. Mobile Driver's License (mDL): The ISO 18013-5 standard uses CBOR to structure digital identity documents.

๐Ÿ”ข CBOR Structure: The 8 Major Types

CBOR organizes its data into 8 major types, identified by the 3 high-order bits of the first byte:

TypeNameDescription

0

Unsigned Integer

Positive integer (0 to 2โถโด-1)

1

Negative Integer

Negative integer (-1 to -2โถโด)

2

Byte String

Raw binary data

3

Text String

UTF-8 string

4

Array

Ordered array

5

Map

Key/value dictionary

6

Tag

Semantic metadata

7

Simple/Float

Booleans, null, floats

Variable-Length Encoding

CBOR uses smart encoding where small values occupy fewer bytes:

Semantic Tags

Tags (major type 6) add context to data. Some common tags:

TagMeaning

0

ISO 8601 date/time

1

Unix timestamp

2

Positive bignum

3

Negative bignum

24

Encapsulated CBOR data

55799

Self-describing CBOR

๐Ÿ“Š Serialization Format Comparison

CriterionJSONCBORMessagePackProtocol Buffers

Format

Text

Binary

Binary

Binary

Schema required

No

No

No

Yes

Typical size

100%

50-70%

50-70%

40-60%

Parsing

Slow

Fast

Fast

Very fast

Binary types

Base64

Native

Native

Native

Extensibility

Limited

Tags

Types

Versions

iOS adoption

Native

Third-party libs

Third-party libs

Third-party libs

๐Ÿ› ๏ธ Swift Ecosystem Status

Apple does not provide a native framework for CBOR. Two open-source libraries dominate the ecosystem:

SwiftCBOR

SwiftCBOR offers a low-level API with direct manipulation of CBOR types.

Strengths: Lightweight, no dependencies, full control over encoding. Weaknesses: No native Codable integration, verbose API for complex cases.

PotentCodables

PotentCodables provides a complete suite of encoders/decoders (CBOR, ASN.1, YAML, JSON) with Codable integration.

Strengths: Codable integration, ASN.1/DER support, consistent API. Weaknesses: Heavier, transitive dependencies.

๐Ÿš€ Practical Implementation

Installation via Swift Package Manager

Basic Encoding and Decoding with SwiftCBOR

Codable Integration with PotentCodables

Custom Types with Numeric Keys (ISO 18013-5 style)

For protocols like mDL that use numeric keys rather than strings:

๐Ÿ” COSE: CBOR Signing and Encryption

COSE (CBOR Object Signing and Encryption), defined in RFC 9052 and RFC 9053, is the CBOR counterpart of JOSE (JSON Object Signing and Encryption). It's used in WebAuthn, COVID certificates, and mDLs.

COSE_Sign1 Structure

The most common structure for single-signer signatures:

COSE Implementation with CryptoKit

๐Ÿ“œ ASN.1: The Grandfather of Binary Serialization

Before CBOR, there was ASN.1 (Abstract Syntax Notation One). This standard from the 80s remains ubiquitous in cryptography: X.509 certificates, PKCS#8 keys, CMS signatures. Understanding ASN.1 is essential for anyone working with CryptoKit and key exchange formats.

What is ASN.1?

ASN.1 is a data description language, not an encoding format itself. It defines the structure, then encoding rules transform it into bytes:

BER (Basic Encoding Rules): Flexible encoding, multiple representations possible for the same data. DER (Distinguished Encoding Rules): Subset of BER, deterministic โ€” one representation per data. DER is used for certificates and signatures. PER, XER, JER: Other encodings (compact, XML, JSON) less common.

CBOR vs ASN.1: When to Use Which?

CriterionCBORASN.1/DER

Era

2013

1984

Complexity

Simple

Complex

Schema required

No

Yes (implicit)

Main usage

IoT, WebAuthn, mDL

Certificates, PKI, CMS

Parsing

Easy

Difficult

Swift ecosystem

Limited

Very limited

In practice: use CBOR for your new protocols, but you'll need to handle ASN.1 as soon as you touch certificates or key export.

TLV Structure (Tag-Length-Value)

ASN.1/DER uses a TLV structure similar to CBOR but more verbose:

Tags identify the type:

TagTypeDescription

0x02

INTEGER

Signed integer

0x03

BIT STRING

Bit string

0x04

OCTET STRING

Binary data

0x05

NULL

Null value

0x06

OBJECT IDENTIFIER

OID (algorithm identifier)

0x0C

UTF8String

UTF-8 string

0x13

PrintableString

Restricted ASCII string

0x17

UTCTime

Date/time

0x30

SEQUENCE

Ordered structure

0x31

SET

Unordered set

ASN.1 Implementation with PotentCodables

PotentCodables offers complete ASN.1 support via the PotentASN1 module. Encoding and decoding require defining a schema that describes the expected ASN.1 structure:

Encoding a Custom ASN.1 Structure

Let's create a structure to encapsulate a signature with its metadata:

Converting Between CBOR and ASN.1

Sometimes you need to convert data between the two formats โ€” for example, to integrate CBOR keys (COSE_Key) with X.509 certificates:

โšก Performance and Best Practices

Typical Benchmarks

In an iOS context, here are the typical orders of magnitude:

OperationJSONCBORGain

Encoding 1000 objects

45ms

28ms

37%

Decoding 1000 objects

52ms

31ms

40%

Payload size

100KB

62KB

38%

When to Use CBOR?

Recommended:

    • IoT/embedded communication (CoAP, LwM2M)
    • Authentication protocols (WebAuthn, FIDO2)
    • Digital identity documents (mDL, EUDI Wallet)
    • Intensive binary data exchange
    • Bandwidth-constrained environments

Avoid:

    • Classic REST APIs (native JSON is simpler)
    • Frequent debugging (CBOR is less readable)
    • Maximum interoperability required (JSON is more universal)

When to Use ASN.1?

Recommended:

    • X.509 certificate manipulation
    • Cryptographic key export/import
    • Integration with existing PKI
    • Legacy protocols (LDAP, SNMP, etc.)

Avoid:

    • New protocols (prefer CBOR)
    • Modern APIs (prefer JSON or CBOR)

Debugging CBOR: Diagnostic Notation

CBOR defines a diagnostic notation for debugging, similar to JSON but more explicit:

Unit Tests with Swift Testing

๐Ÿ”ฎ Perspectives: Identity Document Services

CBOR is at the heart of the digital identity revolution. The ISO 18013-5 standard defines the Mobile Driver's License (mDL), and the future EUDI (European Digital Identity) regulation builds on these same foundations.

In an upcoming article, we'll explore in detail the Identity Document Services introduced in iOS 26, and how Apple integrates these standards to enable identity verification directly from your applications.

Going Further

Official Specifications

Swift Libraries

Identity Standards