{"id":7675,"library":"rfc8785","title":"RFC 8785 (JSON Canonicalization Scheme)","description":"rfc8785.py is a pure-Python, no-dependency implementation of RFC 8785, also known as the JSON Canonicalization Scheme (JCS). It provides deterministic serialization of JSON data, essential for cryptographic operations like hashing and signing where byte-identical representations are required for logically equivalent data. The library is actively maintained, with version 0.1.4 being the latest stable release, and it follows an irregular release cadence driven by contributions and fixes.","status":"active","version":"0.1.4","language":"en","source_language":"en","source_url":"https://github.com/trailofbits/rfc8785.py","tags":["json","canonicalization","security","cryptography","jcs","serialization"],"install":[{"cmd":"pip install rfc8785","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"The primary function for canonicalizing a Python object to bytes.","symbol":"dumps","correct":"import rfc8785\ncanonical_json = rfc8785.dumps(...)"},{"note":"For direct canonicalization to a bytes I/O sink.","symbol":"dump","correct":"import rfc8785\nwith open('file.jcs', 'wb') as f:\n    rfc8785.dump(my_data, f)"},{"note":"Base exception for all errors during canonicalization.","symbol":"CanonicalizationError","correct":"from rfc8785 import CanonicalizationError\ntry:\n    ...\nexcept CanonicalizationError as e:\n    ..."}],"quickstart":{"code":"import rfc8785\n\ndata = {\n    \"name\": \"Alice\",\n    \"age\": 30,\n    \"isStudent\": False,\n    \"courses\": [\"Math\", \"Science\"],\n    \"address\": {\n        \"city\": \"New York\",\n        \"zip\": \"10001\"\n    }\n}\n\ncanonical_bytes = rfc8785.dumps(data)\nprint(canonical_bytes.decode('utf-8'))","lang":"python","description":"Demonstrates how to use `rfc8785.dumps` to get the canonical byte representation of a Python dictionary. The output is always UTF-8 encoded bytes with keys sorted lexicographically, and specific number and literal serialization as per RFC 8785."},"warnings":[{"fix":"Ensure all dictionary keys in the input data are strings before passing to `rfc8785.dumps` or `rfc8785.dump`.","message":"As of v0.1.3, the library explicitly raises `CanonicalizationError` when encountering non-string dictionary keys, rather than attempting implicit conversion or silent failure.","severity":"breaking","affected_versions":">=0.1.3"},{"fix":"Call `.decode('utf-8')` on the result of `rfc8785.dumps` if a string is needed (e.g., `rfc8785.dumps(data).decode('utf-8')`).","message":"All API functions (`dumps`, `dump`) produce UTF-8 encoded `bytes` objects or write to `bytes` I/O, not standard Python `str` objects. You must decode the output if a string is required.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure numbers adhere to IEEE 754 double-precision standards. Large integers or special float values (NaN, Inf) must be serialized as strings in the input data if they are not representable.","message":"The library enforces strict number serialization according to ECMAScript's IEEE 754 double-precision float representation, raising `IntegerDomainError` or `FloatDomainError` for integers exceeding this precision or floats like NaN/Infinity.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Do not expect or attempt to configure `rfc8785` for human-readable output; its purpose is machine-readable canonicalization.","message":"rfc8785.py explicitly does not support indentation or pretty-printing. The output is always minimally encoded as required by JCS.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Convert all dictionary keys to strings before passing the data to `rfc8785.dumps` or `rfc8785.dump`.","cause":"Attempting to serialize a dictionary with non-string keys (e.g., integers, tuples) directly.","error":"rfc8785.CanonicalizationError: Non-string object keys are not supported."},{"fix":"Ensure all data types are standard JSON-compatible (strings, numbers, booleans, null, lists, dictionaries). Custom objects or unsupported types must be converted before canonicalization.","cause":"Input data contains types not supported by standard JSON, or custom objects without a defined serialization method. This is a common Python JSON serialization error, also applicable here.","error":"TypeError: Object of type X is not JSON serializable"},{"fix":"For very large integers that exceed IEEE 754 precision, convert them to strings in your input data before canonicalization, as per common JSON practices for large numbers.","cause":"An integer in the input data exceeds the maximum safe integer precision for an IEEE 754 double-precision float.","error":"rfc8785.IntegerDomainError: The given integer exceeds the true integer precision of an IEEE 754 double-precision float, which is what JSON uses."}]}