|  |
| --- |
| |
| [](https://codecov.io/gh/benmcollins/libjwt) |
| |
| [](https://maclara-llc.com) |
| |
| ## :bulb: Supported Standards |
| |
| Standard | RFC | Description |
| -------- | :------------------------------------------------------------------------: | ---------------------- |
| ``JWS`` | :page_facing_up: [RFC-7515](https://datatracker.ietf.org/doc/html/rfc7515) | JSON Web Signature |
| ``JWE`` | :page_facing_up: [RFC-7516](https://datatracker.ietf.org/doc/html/rfc7516) | JSON Web Encryption |
| ``JWK`` | :page_facing_up: [RFC-7517](https://datatracker.ietf.org/doc/html/rfc7517) | JSON Web Keys and Sets |
| ``JWA`` | :page_facing_up: [RFC-7518](https://datatracker.ietf.org/doc/html/rfc7518) | JSON Web Algorithms |
| ``JWT`` | :page_facing_up: [RFC-7519](https://datatracker.ietf.org/doc/html/rfc7519) | JSON Web Token |
| |
| > [!NOTE] |
| > Throughout this documentation you will see links such as the ones |
| > above to RFC documents. These are relevant to that particular part of the |
| > library and are helpful to understand some of the specific standards that |
| > shaped the development of LibJWT. |
| |
| ## :construction: Build Prerequisites |
| |
| ### Required |
| |
| - A JSON library: either [Jansson](https://github.com/akheron/jansson) |
| (>= 2.0, the default) or [json-c](https://github.com/json-c/json-c) |
| (>= 0.16, selected with ``-DWITH_JSON_C=ON``). The two are interchangeable. |
| - [CMake](https://cmake.org) (>= 3.7) |
| |
| ### Crypto support |
| |
| - OpenSSL (>= 3.0.0) |
| - GnuTLS (>= 3.8.8) |
| - MbedTLS (>= 3.6.0) |
| |
| > [!NOTE] |
| > At least one crypto backend is required, but any non-empty combination |
| > works. OpenSSL is enabled by default and can be disabled with |
| > ``-DWITH_OPENSSL=OFF``. Each backend parses and converts JWK(S) natively. |
| |
| ### Algorithm support matrix |
| |
| JWS Algorithm ``alg`` | OpenSSL | GnuTLS | MbedTLS |
| :---------------------------- | :----------------- | :----------------- | :---------------------- |
| ``HS256`` ``HS384`` ``HS512`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``ES256`` ``ES384`` ``ES512`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``RS256`` ``RS384`` ``RS512`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``EdDSA`` using ``ED25519`` [^okp3813] | :white_check_mark: | :white_check_mark: | :x: |
| ``EdDSA`` using ``ED448`` [^okp3813] | :white_check_mark: | :white_check_mark: | :x: |
| ``PS256`` ``PS384`` ``PS512`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``ES256K`` | :white_check_mark: | :x: | :white_check_mark: |
| ``ML-DSA-44/65/87`` [^mldsa] | :white_check_mark: | :white_check_mark: | :x: |
| |
| [^mldsa]: ML-DSA (FIPS 204, registered for JOSE by |
| [RFC 9964](https://datatracker.ietf.org/doc/rfc9964/)) is **experimental** and |
| **off by default**. Build with ``-DWITH_ML_DSA=ON``; it is only enabled when a |
| backend with ML-DSA support is present: OpenSSL >= 3.5, or GnuTLS >= 3.8.10 |
| built against a PQC provider (e.g. ``--with-leancrypto``). When built in, the |
| public header defines ``LIBJWT_HAVE_ML_DSA``. ML-DSA keys use the ``"AKP"`` key |
| type with a ``"pub"`` member and a ``"priv"`` member holding the 32-byte |
| FIPS-204 seed. MbedTLS has no ML-DSA and rejects ``AKP`` keys. |
| |
| [^okp3813]: On the **GnuTLS** backend these specific cases need **GnuTLS >= |
| 3.8.13**: (a) loading an OKP *private* JWK supplied without its public |
| coordinate ``x``, a "seed-only" ``Ed25519``/``Ed448`` key (older GnuTLS |
| crashes deriving the public key); and (b) ``ECDH-ES`` with the ``X25519`` and |
| ``X448`` curves. Anything that carries ``x`` (including every public key and |
| every PEM/DER key) is unaffected, as are the OpenSSL and MbedTLS backends. The |
| version is checked at **runtime**, so upgrading the shared ``libgnutls`` to >= |
| 3.8.13 lifts the restriction without rebuilding LibJWT. |
| |
| #### JWE |
| |
| LibJWT supports JWE (RFC 7516) in both the Compact Serialization and the JSON |
| Serialization (the Flattened form and the General form with one or more |
| recipients). A JWE uses two algorithms: a key management algorithm (``alg``) |
| and a content encryption algorithm (``enc``). |
| |
| | JWE serialization | Recipients | Supported | |
| | :---------------- | :--------- | :-------- | |
| | Compact (RFC 7516 §7.1) | one | :white_check_mark: | |
| | JSON Flattened (RFC 7516 §7.2.2) | one | :white_check_mark: | |
| | JSON General (RFC 7516 §7.2.1) | one or more | :white_check_mark: | |
| |
| With the JSON serializations the plaintext is encrypted once with a single CEK; |
| each recipient wraps that CEK independently, so any recipient's key can decrypt |
| the token. They also carry an optional shared unprotected header, per-recipient |
| headers, and an application AAD member. |
| |
| Legend: :white_check_mark: native implementation · :x: not supported |
| |
| JWE key management ``alg`` | OpenSSL | GnuTLS | MbedTLS |
| :---------------------------- | :----------------- | :----------------- | :----------------- |
| ``dir`` (Direct Encryption) | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``A128KW`` ``A192KW`` ``A256KW`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``RSA-OAEP`` (SHA-1) | :white_check_mark: | :x: | :white_check_mark: |
| ``RSA-OAEP-256`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``ECDH-ES`` (+ ``+A128KW``/``+A192KW``/``+A256KW``) [^okp3813] | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| |
| JWE content encryption ``enc`` | OpenSSL | GnuTLS | MbedTLS |
| :----------------------------- | :----------------- | :----------------- | :----------------- |
| ``A128GCM`` ``A192GCM`` ``A256GCM`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ``A128CBC-HS256`` ``A192CBC-HS384`` ``A256CBC-HS512`` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| |
| > [!NOTE] |
| > ``ECDH-ES`` supports both Direct Key Agreement and the ``+A*KW`` key |
| > wrapping modes, on the EC curves P-256/384/521 and the OKP curves |
| > X25519/X448, with optional ``apu``/``apv`` PartyInfo. ``RSA1_5`` and |
| > ``zip`` (compression) are intentionally not supported. Each backend |
| > implements JWE natively. GnuTLS/Nettle cannot perform RSA-OAEP with SHA-1, |
| > so the GnuTLS backend does not support plain ``RSA-OAEP`` (``RSA-OAEP-256`` |
| > is native). |
| |
| ### Optional |
| |
| - [Check Library](https://github.com/libcheck/check/issues) (>= 0.9.10) for unit |
| testing |
| - [Doxygen](https://www.doxygen.nl) (>= 1.13.0) for documentation |
| |
| ## :books: Docs and Source |
| |
| :link: [Current Docs](https://libjwt.io) |
| |
| :link: [Legacy Docs v2.1.1](https://libjwt.io/stable) |
| |
| :link: [GitHub Repo](https://github.com/benmcollins/libjwt) |
| |
| ## :package: Pre-built Packages |
| |
| LibJWT is available in most Linux distributions as well as through |
| [Homebrew](https://formulae.brew.sh/formula/libjwt#default) |
| for Linux, macOS, and Windows. |
| |
| ## :hammer: Build Instructions |
| |
| ### With CMake: |
| |
| $ mkdir build |
| $ cd build |
| $ cmake .. |
| $ make |