CBOR Encoder & Decoder: Convert JSON to Binary and Back (RFC 8949)
Learn how to encode and decode CBOR, the compact binary JSON format behind WebAuthn, COSE, and IoT, with a free online CBOR encoder/decoder tool.
Table of Contents
If you have ever inspected a WebAuthn registration response, poked at a COSE key, or worked with an IoT device that speaks CoAP, you have already met CBOR. Concise Binary Object Representation, standardized in RFC 8949, is the Internet's answer to a simple question: what would JSON look like if it were designed for machines instead of humans? The result is a binary format that keeps JSON's data model β objects, arrays, strings, numbers, booleans, null β but packs it into a fraction of the bytes.
The problem is that binary data is awkward to read. A CBOR payload arrives as raw bytes, usually shown as an opaque hex string like a36568656c6c6f65776f726c64, and making sense of it requires either a library in your project or a decoder you can trust. That is exactly why we built the free CBOR Encoder / Decoder. Paste JSON and get CBOR bytes back as hex and Base64, or paste CBOR bytes and get readable JSON β all in one screen.
Everything runs client-side in your browser. The encoder and decoder are implemented in pure JavaScript following RFC 8949, so your payloads never leave your machine, which matters when you are debugging real authentication data or proprietary device protocols.
Why Use CBOR?
- Dramatically smaller payloads. CBOR typically saves 40β60% over equivalent JSON. There are no quotes around keys, no colons or commas between elements, and small integers compress to a single byte. On battery-powered IoT devices or metered mobile connections, that difference adds up fast.
- WebAuthn and FIDO2 depend on it. Passkeys and security keys speak CBOR natively. The attestationObject and authenticatorData fields in every WebAuthn registration ceremony are CBOR maps, so anyone building or debugging passwordless login needs to read CBOR regularly.
- COSE and CWT build on it. COSE (RFC 9052) defines signed and encrypted security objects on top of CBOR, and CBOR Web Tokens (CWT, RFC 8392) are the binary cousin of JWTs β popular in constrained environments where JWT parsing overhead is too expensive.
- It is the standard codec for CoAP and IoT. The Constrained Application Protocol (RFC 7252) pairs naturally with CBOR, and sensor networks, smart meters, and embedded firmware teams use it as their default serialization.
- Binary-native types JSON lacks. CBOR has true byte strings, half-precision floats, 64-bit integers beyond JavaScript's safe range, and tags for semantic values like timestamps β none of which JSON can represent without lossy workarounds like Base64-in-a-string.
- Deterministic encoding for signing. CBOR supports canonical (deterministic) forms such as dCBOR, where the same logical value always produces the same bytes β essential for digital signatures, where two encoders disagreeing by one byte breaks verification.
Key Features
| Feature | What it does |
|---|---|
| JSON β CBOR encoding | Converts any valid JSON document into CBOR bytes |
| CBOR β JSON decoding | Parses hex or Base64 CBOR back into readable JSON |
| Dual output views | Encode mode shows Base64 and hex side by side; decode mode shows JSON and the raw hex bytes |
| Full major-type coverage | Integers (including negative values and BigInt ranges), byte strings, text strings, arrays, maps, tags, and simple values |
| All float widths | Half-precision (f16), single-precision (f32), and double-precision (f64) |
| 100% client-side | Pure JavaScript implementation of RFC 8949; no uploads, no server round-trips |
Two details deserve a call-out. First, byte strings survive decoding intact: they are rendered as objects carrying __cbor_bstr__ (Base64) and __cbor_hex__ (hex) fields instead of being mangled through UTF-8. Second, when a map uses byte strings as keys, they are shown in diagnostic notation (h'...'), which is exactly how RFC 8949 examples are written β so what you see matches the specs you read.
Error handling is also precise. Instead of a generic "parse failed", the decoder reports issues like unexpected end of CBOR input or byte string length out of range, which points you straight at truncated payloads β one of the most common failures when copying hex by hand.
How to Use the CBOR Encoder / Decoder
- Pick your mode. Toggle between Encode and Decode with the two buttons at the top of the tool.
- Paste your input. In Encode mode, paste a JSON document such as {"hello": "world"}. In Decode mode, paste CBOR bytes as a hex string or Base64.
- Run the conversion. The tool parses the input immediately and flags malformed JSON or invalid byte sequences with a specific error message.
- Read both outputs. Encode mode gives you the CBOR bytes in Base64 and hex; Decode mode gives you the JSON representation plus a hex view of the bytes you fed in.
- Copy the result. Copy whichever representation you need straight into your code, test fixture, or bug report.
Understanding CBOR: Major Types and Encoding
CBOR's entire structure rests on eight major types, each identified by the top three bits of the first byte (the "initial byte"):
| Major type | Value | Represents |
|---|---|---|
| 0 | 0β7 | Unsigned integers |
| 1 | 8β15 | Negative integers |
| 2 | 16β23 | Byte strings |
| 3 | 24β31 | UTF-8 text strings |
| 4 | 32β39 | Arrays |
| 5 | 40β47 | Maps (key-value pairs) |
| 6 | 48β55 | Tags (semantic annotations) |
| 7 | 56β63 | Simple values and floats |
The remaining five bits of the initial byte encode the "additional information" β either the argument value itself (for small numbers) or its length. Values 0β23 are stored inline. 24 means "one more byte follows", 25 means two bytes (also used for half-precision floats), 26 means four bytes (single-precision floats), and 27 means eight bytes (double-precision floats and 64-bit integers).
A concrete example makes this click. Take {"hello": "world"}:
a1 map with 1 pair 65 text string, 5 bytes long 68656c6c6f "hello" 65 text string, 5 bytes long 776f726c64 "world"
The first byte 0xa1 is major type 5 (map) with length 1. Then 0x65 is major type 3 (text) with a 5-byte payload β the hex for "hello". The value follows the same pattern for "world". Total: 13 bytes, versus 17 bytes for the JSON text, and the gap widens as documents grow because JSON keeps paying for quotes, colons, and commas on every element.
Integers show the compression even more starkly. The number 42 fits in the additional-information bits alone: the entire encoding is the single byte 0x18 0x2a only when it exceeds the inline range β in fact 42 encodes as just 0x2a (major type 0, value 42 inline). No sign character, no decimal digits, no delimiter.
Floats follow the preferred-encoding rule from RFC 8949: use the shortest float width that preserves the value. The decoder honors all three widths (f16, f32, f64), and large integers beyond JavaScript's Number.MAX_SAFE_INTEGER round-trip through BigInt, so a 64-bit ID or timestamp does not silently lose precision.
Practical Use Cases
Debugging WebAuthn registration and authentication
When a passkey registration fails, the fastest diagnosis is to decode the attestationObject. Base64-url-decode it (our Base64 Encoder handles that step), then paste the bytes into the CBOR decoder in hex form. You get the three expected map keys β fmt, attStmt, and authData β plus the nested authenticator data, where you can verify flags, the signature counter, and the credential ID length instead of guessing which layer broke.
Inspecting COSE keys and CWT tokens
COSE public keys (labeled maps with key type, algorithm, and curve parameters) and CWT claims sets are both CBOR. If you are integrating a security library or validating a token from a constrained device, decoding the payload reveals the algorithm identifiers and claim labels as numbers, letting you confirm the exact parameters against the IANA registry rather than trusting error messages.
Shrinking IoT and CoAP payloads
Firmware teams routinely migrate sensor telemetry from JSON to CBOR to fit messages into single network frames. A typical reading like {"temp": 22.5, "hum": 61, "batt_mv": 3310} shrinks from around 40 bytes to under 20. Use the encoder to convert your JSON schema to CBOR, measure the real byte counts in the hex output, and confirm the savings before committing firmware changes.
Verifying binary API responses and test fixtures
If your backend returns CBOR (common with gRPC-adjacent stacks, device gateways, or HTTP + CBOR APIs), you can paste a captured response into the decoder to check field names and values during development, then use the encoder in the opposite direction to build fixture bytes for unit tests β with the hex view serving as your source of truth for expected bytes.
Best Practices
- Validate hex input carefully. A single missing byte in a hand-copied hex string truncates the payload and shifts every subsequent parse. If the decoder reports unexpected end of CBOR input, count your bytes before assuming the data is corrupt.
- Prefer deterministic encoding when signing. If bytes feed into a signature, encode with Core Deterministic Encoding (or dCBOR) rules so every encoder produces identical bytes. Round-trip convenience is fine for debugging, but signatures demand determinism.
- Respect preferred float encoding. RFC 8949 prefers the shortest float that round-trips. Encoders that always emit f64 produce larger payloads and can break interop with strict validators on constrained devices.
- Keep byte strings as bytes. Do not convert binary data to a UTF-8 string before encoding β that corrupts non-ASCII bytes. Use CBOR byte strings (major type 2) directly, which is exactly what the tool's __cbor_bstr__/__cbor_hex__ output preserves.
- Watch integer boundaries. Values above 2^53 lose precision in plain JavaScript numbers. Use BigInt-capable tooling (this decoder supports it) when handling 64-bit IDs or timestamps.
- Round-trip test your payloads. Encode your JSON, decode the result, and compare. Any mismatch signals a type assumption problem β usually a byte string coerced to text or a float precision issue β better caught at your desk than in production.
Start Encoding and Decoding CBOR Today
Binary formats stop being intimidating the moment you can see inside them. Whether you are untangling a WebAuthn attestation, validating a COSE structure, slimming down firmware payloads, or just curious what those hex bytes contain, the CBOR Encoder / Decoder gives you an instant, private, standards-accurate window into RFC 8949 β no installation, no account, no data leaving your browser.
Related Tools You Might Like
- JSON Formatter β pretty-print and validate the JSON you get after decoding
- JWT Decoder β inspect header and claims of text-based JWTs
- Base64 Encoder β convert between Base64 and raw text or bytes
Happy encoding!