CBOR
ActiveBinary data format whose design goals include extremely small code size, compact message size, and extensibility without version negotiation. Used in IoT, FIDO2, WebAuthn, COSE, and CWT.
In one line
CBOR (Concise Binary Object Representation) is defined by RFC 8949 (STD 94). It encodes the same data model as JSON in binary with significantly smaller message sizes. CBOR uses 8 major type groups (0-7) encoded in the first byte. Used in FIDO2/WebAuthn, IoT (CoAP), COSE (signing), and CWT (tokens).
Quick Reference
| Field | Size | Description |
|---|---|---|
| First byte | 1 byte | Upper 3 bits = major type (0-7). Lower 5 bits = additional info (argument). |
| Major type 0 | uint | Unsigned integer. 0x00-0x17 = direct value. 0x18 = 1-byte follow. 0x19 = 2-byte. 0x1a = 4-byte. 0x1b = 8-byte. |
| Major type 1 | nint | Negative integer. Value = -1 - argument. 0x20 = -1, 0x37 = -24. |
| Major type 2 | bstr | Byte string. Length in argument, then raw bytes. |
| Major type 3 | tstr | Text string (UTF-8). Length in argument, then UTF-8 bytes. |
| Major type 4 | array | Array. Count in argument, then items. |
| Major type 5 | map | Map (key-value pairs). Count in argument, then key-value pairs. |
| Major type 6 | tag | Tagged item. Tag number in argument wraps the next data item. |
| Major type 7 | float/simple | Floating-point numbers, simple values (false=0xf4, true=0xf5, null=0xf6), and break (0xff). |
Key Characteristics
Compact binary
Small integers encode in 1 byte. A map with string keys is significantly smaller than equivalent JSON.
JSON superset
CBOR can encode everything JSON can, plus binary data, 64-bit integers, and typed arrays without base64 overhead.
FIDO2/WebAuthn
CBOR is the wire format for authenticatorData, attestationObject, and COSE keys in WebAuthn. If you build passkeys, you parse CBOR.
Self-describing
CBOR data items are self-delimiting. No schema needed to parse. Tags provide optional semantic annotations.
Message Format
// JSON equivalent vs CBOR (hex)
// JSON: {"a":1} = 7 bytes
// CBOR: a1 61 61 01 = 4 bytes
// CBOR encoding examples:
// true = 0xf5 (1 byte)
// false = 0xf4 (1 byte)
// null = 0xf6 (1 byte)
// 0 = 0x00 (1 byte)
// 23 = 0x17 (1 byte)
// 24 = 0x18 0x18 (2 bytes)
// -1 = 0x20 (1 byte)
// "hello" = 0x65 0x68 0x65 0x6c 0x6c 0x6f (6 bytes)
// [1,2] = 0x82 0x01 0x02 (3 bytes)// CBOR diagnostic notation (human-readable equivalent)
// 0xa2 -- map(2)
// 0x61 0x61 -- text(1) "a"
// 0x01 -- uint(1)
// 0x61 0x62 -- text(1) "b"
// 0x82 0x01 0x02 -- array(2) [1, 2]
// WebAuthn authenticatorData starts with:
// 32 bytes rpIdHash (SHA-256 of relying party ID)
// 1 byte flags (UP, UV, BE, BS, AT, ED bits)
// 4 bytes signCount (big-endian uint32)