{"id":13508438,"url":"https://github.com/potatosalad/erlang-jose","last_synced_at":"2025-05-14T02:07:31.061Z","repository":{"id":35530460,"uuid":"39801338","full_name":"potatosalad/erlang-jose","owner":"potatosalad","description":"JSON Object Signing and Encryption (JOSE) for Erlang and Elixir","archived":false,"fork":false,"pushed_at":"2025-03-26T11:31:54.000Z","size":1691,"stargazers_count":321,"open_issues_count":32,"forks_count":104,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-13T19:02:51.060Z","etag":null,"topics":["cryptography","elixir","erlang","jose","jwt"],"latest_commit_sha":null,"homepage":"http://hexdocs.pm/jose","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/potatosalad.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-07-27T22:40:04.000Z","updated_at":"2025-05-11T11:23:15.000Z","dependencies_parsed_at":"2023-01-15T22:53:35.312Z","dependency_job_id":"27145a01-59a6-4e08-950d-281eaf9ae2f3","html_url":"https://github.com/potatosalad/erlang-jose","commit_stats":{"total_commits":257,"total_committers":43,"mean_commits":5.976744186046512,"dds":0.5525291828793775,"last_synced_commit":"eb6de2cb506b55533f550a1b0776c81b15317e23"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potatosalad%2Ferlang-jose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potatosalad%2Ferlang-jose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potatosalad%2Ferlang-jose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potatosalad%2Ferlang-jose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/potatosalad","download_url":"https://codeload.github.com/potatosalad/erlang-jose/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052852,"owners_count":22006717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","elixir","erlang","jose","jwt"],"created_at":"2024-08-01T02:00:53.062Z","updated_at":"2025-05-14T02:07:26.044Z","avatar_url":"https://github.com/potatosalad.png","language":"Erlang","funding_links":[],"categories":["JSON","Security"],"sub_categories":["Cryptography"],"readme":"# JOSE\n\n[![Build Status](https://github.com/potatosalad/erlang-jose/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/potatosalad/erlang-jose/actions) [![Hex.pm](https://img.shields.io/hexpm/v/jose.svg)](https://hex.pm/packages/jose)\n\nJSON Object Signing and Encryption (JOSE) for Erlang and Elixir.\n\n## Installation\n\nAdd `jose` to your project's dependencies in `mix.exs`\n\n```elixir\ndefp deps() do\n  [\n    {:jose, \"~\u003e 1.11\"}\n  ]\nend\n```\n\nIf you are using deployment tools (`exrm`, etc.) and your app depends\non `jose` directly, you will need to include `jose` in your\napplications list in `mix.exs` to ensure they get compiled into your\nrelease:\n\n```elixir\ndef application() do\n  [\n    mod: {YourApp, []},\n    applications: [:jose]\n  ]\nend\n```\n\nAdd `jose` to your project's dependencies in your `Makefile` for [`erlang.mk`](https://github.com/ninenines/erlang.mk) or the following to your `rebar.config`\n\n```erlang\n{deps, [\n  jose\n]}.\n```\n\n#### JSON Encoder/Decoder\n\nYou will also need to specify either [jiffy](https://github.com/davisp/jiffy), [jsone](https://github.com/sile/jsone), [jsx](https://github.com/talentdeficit/jsx), [ojson](https://github.com/potatosalad/erlang-ojson), [Poison](https://github.com/devinus/poison), or [Jason](https://github.com/michalmuskala/jason) as a dependency.\n\nFor example, with Elixir and `mix.exs`\n\n```elixir\ndefp deps() do\n  [\n    {:jose, \"~\u003e 1.11\"},\n    {:jason, \"~\u003e 1.4\"}\n  ]\nend\n```\n\nOr with Erlang and `rebar.config`\n\n```erlang\n{deps, [\n  jose,\n  ojson\n]}.\n```\n\n`jose` will attempt to find a suitable JSON encoder/decoder and will try to use (in order) ojson, Jason, Poison, jiffy, jsone, or jsx.\n\nYou may also specify a different `json_module` as an application environment variable to `jose` or by using `jose:json_module/1` or `JOSE.json_module/1`.\n\n#### ChaCha20/Poly1305 Support\n\nChaCha20/Poly1305 encryption and one-time message authentication functions are experimentally supported based on [RFC 7539](https://tools.ietf.org/html/rfc7539).\n\nFallback support for `ChaCha20/Poly1305` encryption and `Poly1305` signing is also provided.  See [`crypto_fallback`](#cryptographic-algorithm-fallback) below.\n\nExternal support is also provided by the following libraries:\n\n * [libsodium](https://github.com/potatosalad/erlang-libsodium) - `ChaCha20/Poly1305` encryption and `Poly1305` signing\n\nOther modules which implement the `jose_chacha20_poly1305` behavior may also be used as follows:\n\n```elixir\n# ChaCha20/Poly1305\nJOSE.chacha20_poly1305_module(:libsodium)                  # uses a fast Erlang port driver for libsodium\nJOSE.chacha20_poly1305_module(:jose_jwa_chacha20_poly1305) # uses the pure Erlang implementation (slow)\n```\n\n#### Curve25519 and Curve448 Support\n\nCurve25519 and Curve448 and their associated signing/key exchange functions are supported now that [RFC 8037](https://tools.ietf.org/html/rfc8037) has been published.\n\nFallback support for `Ed25519`, `Ed25519ph`, `Ed448`, `Ed448ph`, `X25519`, and `X448` is provided.  See [`crypto_fallback`](#cryptographic-algorithm-fallback) below.\n\nExternal support is also provided by the following libraries:\n\n * [libdecaf](https://github.com/potatosalad/erlang-libdecaf) - `Ed25519`, `Ed25519ph`, `Ed448`, `Ed448ph`, `X25519`, `X448`\n * [libsodium](https://github.com/potatosalad/erlang-libsodium) - `Ed25519`, `Ed25519ph`, `X25519`\n\nIf both libraries are present, libdecaf will be used by default.  Other modules which implement the `jose_curve25519` or `jose_curve448` behaviors may also be used as follows:\n\n```elixir\n# Curve25519\nJOSE.curve25519_module(:libdecaf)            # uses a fast Erlang NIF for libdecaf\nJOSE.curve25519_module(:jose_jwa_curve25519) # uses the pure Erlang implementation (slow)\n\n# Curve448\nJOSE.curve448_module(:libdecaf)          # uses a fast Erlang NIF for libdecaf\nJOSE.curve448_module(:jose_jwa_curve448) # uses the pure Erlang implementation (slow)\n```\n\n#### SHA-3 Support\n\nSHA-3 is experimentally supported for use with `Ed448` and `Ed448ph` signing functions.\n\nFallback support for SHA-3 is provided.  See [`crypto_fallback`](#cryptographic-algorithm-fallback) below.\n\nExternal support for SHA-3 is provided by the [keccakf1600](https://github.com/potatosalad/erlang-keccakf1600) and [libdecaf](https://github.com/potatosalad/erlang-libdecaf) libraries.  If present, keccakf1600 will be used by default.  Other modules which implement the `jose_sha3` behaviors may also be used as follows:\n\n```elixir\nJOSE.sha3_module(:keccakf1600)   # uses a NIF written in C with timeslice reductions\nJOSE.sha3_module(:jose_jwa_sha3) # uses the pure Erlang implementation (slow)\n```\n\n#### Cryptographic Algorithm Fallback\n\n`jose` strives to support [all](#algorithm-support) of the cryptographic algorithms specified in the [JOSE RFCs](https://tools.ietf.org/wg/jose/).\n\nHowever, not all of the required algorithms are supported natively by Erlang/Elixir.  For algorithms unsupported by the native [`crypto`](http://www.erlang.org/doc/man/crypto.html) and [`public_key`](http://www.erlang.org/doc/man/public_key.html), `jose` has a pure Erlang implementation that may be used as a fallback.\n\nSee [ALGORITHMS.md](https://github.com/potatosalad/erlang-jose/blob/main/ALGORITHMS.md) for more information about algorithm support for specific OTP versions.\n\nBy default, the algorithm fallback is disabled, but can be enabled by setting the `crypto_fallback` application environment variable for `jose` to `true` or by calling `jose:crypto_fallback/1` or `JOSE.crypto_fallback/1` with `true`.\n\nYou may also review which algorithms are currently supported with the `jose_jwa:supports/0` or `JOSE.JWA.supports/0` functions.  For example, on Elixir 1.9.4 and OTP 22:\n\n```elixir\n# crypto_fallback defaults to false\nJOSE.JWA.supports()\n\n[\n  {:jwe,\n   {:alg,\n    [\"A128GCMKW\", \"A128KW\", \"A192GCMKW\", \"A192KW\", \"A256GCMKW\", \"A256KW\",\n     \"C20PKW\", \"ECDH-1PU\", \"ECDH-1PU+A128GCMKW\", \"ECDH-1PU+A128KW\",\n     \"ECDH-1PU+A192GCMKW\", \"ECDH-1PU+A192KW\", \"ECDH-1PU+A256GCMKW\",\n     \"ECDH-1PU+A256KW\", \"ECDH-1PU+C20PKW\", \"ECDH-1PU+XC20PKW\", \"ECDH-ES\",\n     \"ECDH-ES+A128GCMKW\", \"ECDH-ES+A128KW\", \"ECDH-ES+A192GCMKW\",\n     \"ECDH-ES+A192KW\", \"ECDH-ES+A256GCMKW\", \"ECDH-ES+A256KW\", \"ECDH-ES+C20PKW\",\n     \"ECDH-ES+XC20PKW\", \"ECDH-SS\", \"ECDH-SS+A128GCMKW\", \"ECDH-SS+A128KW\",\n     \"ECDH-SS+A192GCMKW\", \"ECDH-SS+A192KW\", \"ECDH-SS+A256GCMKW\",\n     \"ECDH-SS+A256KW\", \"ECDH-SS+C20PKW\", \"ECDH-SS+XC20PKW\",\n     \"PBES2-HS256+A128GCMKW\", \"PBES2-HS256+A128KW\", \"PBES2-HS384+A192GCMKW\",\n     \"PBES2-HS384+A192KW\", \"PBES2-HS512+A256GCMKW\", \"PBES2-HS512+A256KW\",\n     \"PBES2-HS512+C20PKW\", \"PBES2-HS512+XC20PKW\", \"RSA-OAEP\", \"RSA-OAEP-256\",\n     \"RSA1_5\", \"XC20PKW\", \"dir\"]},\n   {:enc,\n    [\"A128CBC-HS256\", \"A128GCM\", \"A192CBC-HS384\", \"A192GCM\", \"A256CBC-HS512\",\n     \"A256GCM\", \"C20P\", \"XC20P\"]}, {:zip, [\"DEF\"]}},\n  {:jwk, {:kty, [\"EC\", \"OKP\", \"RSA\", \"oct\"]},\n   {:kty_OKP_crv,\n    [\"Ed25519\", \"Ed25519ph\", \"Ed448\", \"Ed448ph\", \"X25519\", \"X448\"]}},\n  {:jws,\n   {:alg,\n    [\"ES256\", \"ES256K\", \"ES384\", \"ES512\", \"Ed25519\", \"Ed25519ph\", \"Ed448\",\n     \"Ed448ph\", \"EdDSA\", \"HS256\", \"HS384\", \"HS512\", \"PS256\", \"PS384\", \"PS512\",\n     \"Poly1305\", \"RS1\", \"RS256\", \"RS384\", \"RS512\"]}}\n]\n\n# setting crypto_fallback to true\nJOSE.crypto_fallback(true)\n\n# additional algorithms are now available for use\nJOSE.JWA.supports()\n\n[\n  {:jwe,\n   {:alg,\n    [\"A128GCMKW\", \"A128KW\", \"A192GCMKW\", \"A192KW\", \"A256GCMKW\", \"A256KW\",\n     \"C20PKW\", \"ECDH-1PU\", \"ECDH-1PU+A128GCMKW\", \"ECDH-1PU+A128KW\",\n     \"ECDH-1PU+A192GCMKW\", \"ECDH-1PU+A192KW\", \"ECDH-1PU+A256GCMKW\",\n     \"ECDH-1PU+A256KW\", \"ECDH-1PU+C20PKW\", \"ECDH-1PU+XC20PKW\", \"ECDH-ES\",\n     \"ECDH-ES+A128GCMKW\", \"ECDH-ES+A128KW\", \"ECDH-ES+A192GCMKW\",\n     \"ECDH-ES+A192KW\", \"ECDH-ES+A256GCMKW\", \"ECDH-ES+A256KW\", \"ECDH-ES+C20PKW\",\n     \"ECDH-ES+XC20PKW\", \"ECDH-SS\", \"ECDH-SS+A128GCMKW\", \"ECDH-SS+A128KW\",\n     \"ECDH-SS+A192GCMKW\", \"ECDH-SS+A192KW\", \"ECDH-SS+A256GCMKW\",\n     \"ECDH-SS+A256KW\", \"ECDH-SS+C20PKW\", \"ECDH-SS+XC20PKW\",\n     \"PBES2-HS256+A128GCMKW\", \"PBES2-HS256+A128KW\", \"PBES2-HS384+A192GCMKW\",\n     \"PBES2-HS384+A192KW\", \"PBES2-HS512+A256GCMKW\", \"PBES2-HS512+A256KW\",\n     \"PBES2-HS512+C20PKW\", \"PBES2-HS512+XC20PKW\", \"RSA-OAEP\", \"RSA-OAEP-256\",\n     \"RSA1_5\", \"XC20PKW\", \"dir\"]},\n   {:enc,\n    [\"A128CBC-HS256\", \"A128GCM\", \"A192CBC-HS384\", \"A192GCM\", \"A256CBC-HS512\",\n     \"A256GCM\", \"C20P\", \"XC20P\"]}, {:zip, [\"DEF\"]}},\n  {:jwk, {:kty, [\"EC\", \"OKP\", \"RSA\", \"oct\"]},\n   {:kty_OKP_crv,\n    [\"Ed25519\", \"Ed25519ph\", \"Ed448\", \"Ed448ph\", \"X25519\", \"X448\"]}},\n  {:jws,\n   {:alg,\n    [\"ES256\", \"ES256K\", \"ES384\", \"ES512\", \"Ed25519\", \"Ed25519ph\", \"Ed448\",\n     \"Ed448ph\", \"EdDSA\", \"HS256\", \"HS384\", \"HS512\", \"PS256\", \"PS384\", \"PS512\",\n     \"Poly1305\", \"RS1\", \"RS256\", \"RS384\", \"RS512\"]}}\n]\n```\n\n#### Unsecured Signing Vulnerability\n\nThe [`\"none\"`](https://tools.ietf.org/html/rfc7515#appendix-A.5) signing algorithm is disabled by default to prevent accidental verification of empty signatures (read about the vulnerability [here](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/)).\n\nIf you want to further restrict the signature algorithms allowed for a token, use `JOSE.JWT.verify_strict/3`:\n\n```elixir\n# Signed Compact JSON Web Token (JWT) with HS256\ntoken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ.shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"\n\n# JSON Web Key (JWK)\njwk = %{\n  \"kty\" =\u003e \"oct\",\n  \"k\" =\u003e :jose_base64url.encode(\"symmetric key\")\n}\n\n{verified, _, _} = JOSE.JWT.verify_strict(jwk, [\"HS256\"], token)\n# {true, _, _}\n\n{verified, _, _} = JOSE.JWT.verify_strict(jwk, [\"RS256\"], token)\n# {false, _, _}\n```\n\nIf you need to inspect the contents of a JSON Web token (JWT) prior to verifying it, use `JOSE.JWT.peek_payload/1` or `JOSE.JWT.peek_protected/1`:\n\n```elixir\ntoken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ.shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"\n\npayload = JOSE.JWT.peek_payload(token)\n# %JOSE.JWT{fields: %{\"exp\" =\u003e 1300819380, \"http://example.com/is_root\" =\u003e true,\n#    \"iss\" =\u003e \"joe\"}}\n\nprotected = JOSE.JWT.peek_protected(token)\n# %JOSE.JWS{alg: {:jose_jws_alg_hmac, {:jose_jws_alg_hmac, :sha256}},\n#  b64: :undefined, fields: %{\"typ\" =\u003e \"JWT\"}}\n\n# If you want to inspect the JSON, you can convert it back to a regular map:\n{_, protected_map} = JOSE.JWS.to_map(protected)\n# {_, %{\"alg\" =\u003e \"HS256\", \"typ\" =\u003e \"JWT\"}}\n```\n\nYou may also enable the `\"none\"` algorithm as an application environment variable for `jose` or by using `jose:unsecured_signing/1` or `JOSE.unsecured_signing/1`.\n\n```elixir\n# unsecured_signing defaults to false\nJOSE.JWA.supports[:jws]\n\n{:alg,\n [\"ES256\", \"ES256K\", \"ES384\", \"ES512\", \"Ed25519\", \"Ed25519ph\", \"Ed448\",\n  \"Ed448ph\", \"EdDSA\", \"HS256\", \"HS384\", \"HS512\", \"PS256\", \"PS384\", \"PS512\",\n  \"Poly1305\", \"RS1\", \"RS256\", \"RS384\", \"RS512\"]}\n\n# setting unsecured_signing to true\nJOSE.unsecured_signing(true)\n\n# the \"none\" algorithm is now available for use\nJOSE.JWA.supports[:jws]\n\n{:alg,\n [\"ES256\", \"ES256K\", \"ES384\", \"ES512\", \"Ed25519\", \"Ed25519ph\", \"Ed448\",\n  \"Ed448ph\", \"EdDSA\", \"HS256\", \"HS384\", \"HS512\", \"PS256\", \"PS384\", \"PS512\",\n  \"Poly1305\", \"RS1\", \"RS256\", \"RS384\", \"RS512\", \"none\"]}\n```\n\n## Usage\n\n##### JSON Web Signature (JWS) of JSON Web Token (JWT) using HMAC using SHA-256 (HS256) with JSON Web Key (JWK)\n\n_Elixir_\n\n```elixir\n# JSON Web Key (JWK)\njwk = %{\n  \"kty\" =\u003e \"oct\",\n  \"k\" =\u003e :jose_base64url.encode(\"symmetric key\")\n}\n\n# JSON Web Signature (JWS)\njws = %{\n  \"alg\" =\u003e \"HS256\"\n}\n\n# JSON Web Token (JWT)\njwt = %{\n  \"iss\" =\u003e \"joe\",\n  \"exp\" =\u003e 1300819380,\n  \"http://example.com/is_root\" =\u003e true\n}\n\nsigned = JOSE.JWT.sign(jwk, jws, jwt)\n# {%{alg: :jose_jws_alg_hmac},\n#  %{\"payload\" =\u003e \"eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ\",\n#    \"protected\" =\u003e \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\",\n#    \"signature\" =\u003e \"shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"}}\n\ncompact_signed = JOSE.JWS.compact(signed)\n# {%{alg: :jose_jws_alg_hmac},\n#  \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ.shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"}\n\nverified = JOSE.JWT.verify(jwk, compact_signed)\n# {true,\n#  %JOSE.JWT{fields: %{\"exp\" =\u003e 1300819380, \"http://example.com/is_root\" =\u003e true,\n#     \"iss\" =\u003e \"joe\"}},\n#  %JOSE.JWS{alg: {:jose_jws_alg_hmac, :HS256}, b64: :undefined,\n#   fields: %{\"typ\" =\u003e \"JWT\"}}}\n\nverified == JOSE.JWT.verify(jwk, signed)\n# true\n```\n\n_Erlang_\n\n```erlang\n% JSON Web Key (JWK)\nJWK = #{\n  \u003c\u003c\"kty\"\u003e\u003e =\u003e \u003c\u003c\"oct\"\u003e\u003e,\n  \u003c\u003c\"k\"\u003e\u003e =\u003e jose_base64url:encode(\u003c\u003c\"symmetric key\"\u003e\u003e)\n}.\n\n% JSON Web Signature (JWS)\nJWS = #{\n  \u003c\u003c\"alg\"\u003e\u003e =\u003e \u003c\u003c\"HS256\"\u003e\u003e\n}.\n\n% JSON Web Token (JWT)\nJWT = #{\n  \u003c\u003c\"iss\"\u003e\u003e =\u003e \u003c\u003c\"joe\"\u003e\u003e,\n  \u003c\u003c\"exp\"\u003e\u003e =\u003e 1300819380,\n  \u003c\u003c\"http://example.com/is_root\"\u003e\u003e =\u003e true\n}.\n\nSigned = jose_jwt:sign(JWK, JWS, JWT).\n% {#{alg =\u003e jose_jws_alg_hmac},\n%  #{\u003c\u003c\"payload\"\u003e\u003e =\u003e \u003c\u003c\"eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ\"\u003e\u003e,\n%    \u003c\u003c\"protected\"\u003e\u003e =\u003e \u003c\u003c\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\"\u003e\u003e,\n%    \u003c\u003c\"signature\"\u003e\u003e =\u003e \u003c\u003c\"shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"\u003e\u003e}}\n\nCompactSigned = jose_jws:compact(Signed).\n% {#{alg =\u003e jose_jws_alg_hmac},\n%  \u003c\u003c\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEzMDA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlLCJpc3MiOiJqb2UifQ.shLcxOl_HBBsOTvPnskfIlxHUibPN7Y9T4LhPB-iBwM\"\u003e\u003e}\n\nVerified = jose_jwt:verify(JWK, CompactSigned).\n% {true,\n%     #jose_jwt{\n%         fields =\n%             #{\u003c\u003c\"exp\"\u003e\u003e =\u003e 1300819380,\n%               \u003c\u003c\"http://example.com/is_root\"\u003e\u003e =\u003e true,\n%               \u003c\u003c\"iss\"\u003e\u003e =\u003e \u003c\u003c\"joe\"\u003e\u003e}},\n%     #jose_jws{\n%         alg = {jose_jws_alg_hmac,'HS256'},\n%         b64 = undefined,\n%         fields = #{\u003c\u003c\"typ\"\u003e\u003e =\u003e \u003c\u003c\"JWT\"\u003e\u003e}}}\n\nVerified =:= jose_jwt:verify(JWK, Signed).\n% true\n```\n\n##### Reading JSON Web Keys (JWK) from PEM files\n\nThe examples below use three keys created with `openssl`:\n\n```bash\n# RSA Private Key\nopenssl genrsa -out rsa-2048.pem 2048\n\n# EC Private Key (Alice)\nopenssl ecparam -name secp256r1 -genkey -noout -out ec-secp256r1-alice.pem\n\n# EC Private Key (Bob)\nopenssl ecparam -name secp256r1 -genkey -noout -out ec-secp256r1-bob.pem\n```\n\n_Elixir_\n\n```elixir\n# RSA examples\nrsa_private_jwk = JOSE.JWK.from_pem_file(\"rsa-2048.pem\")\nrsa_public_jwk  = JOSE.JWK.to_public(rsa_private_jwk)\n\n## Sign and Verify (defaults to PS256)\nmessage = \"my message\"\nsigned = JOSE.JWK.sign(message, rsa_private_jwk)\n{true, ^message, _} = JOSE.JWK.verify(signed, rsa_public_jwk)\n\n## Sign and Verify (specify RS256)\nsigned = JOSE.JWK.sign(message, %{ \"alg\" =\u003e \"RS256\" }, rsa_private_jwk)\n{true, ^message, _} = JOSE.JWK.verify(signed, rsa_public_jwk)\n\n## Encrypt and Decrypt (defaults to RSA-OAEP with A128CBC-HS256)\nplain_text = \"my plain text\"\nencrypted = JOSE.JWK.block_encrypt(plain_text, rsa_public_jwk)\n{^plain_text, _} = JOSE.JWK.block_decrypt(encrypted, rsa_private_jwk)\n\n## Encrypt and Decrypt (specify RSA-OAEP-256 with A128GCM)\nencrypted = JOSE.JWK.block_encrypt(plain_text, %{ \"alg\" =\u003e \"RSA-OAEP-256\", \"enc\" =\u003e \"A128GCM\" }, rsa_public_jwk)\n{^plain_text, _} = JOSE.JWK.block_decrypt(encrypted, rsa_private_jwk)\n\n# EC examples\nalice_private_jwk = JOSE.JWK.from_pem_file(\"ec-secp256r1-alice.pem\")\nalice_public_jwk  = JOSE.JWK.to_public(alice_private_jwk)\nbob_private_jwk   = JOSE.JWK.from_pem_file(\"ec-secp256r1-bob.pem\")\nbob_public_jwk    = JOSE.JWK.to_public(bob_private_jwk)\n\n## Sign and Verify (defaults to ES256)\nmessage = \"my message\"\nsigned = JOSE.JWK.sign(message, alice_private_jwk)\n{true, ^message, _} = JOSE.JWK.verify(signed, alice_public_jwk)\n\n## Encrypt and Decrypt (defaults to ECDH-ES with A128GCM)\n### Alice sends Bob a secret message using Bob's public key and Alice's private key\nalice_to_bob = \"For Bob's eyes only.\"\nencrypted = JOSE.JWK.box_encrypt(alice_to_bob, bob_public_jwk, alice_private_jwk)\n### Only Bob can decrypt the message using his private key (Alice's public key is embedded in the JWE header)\n{^alice_to_bob, _} = JOSE.JWK.box_decrypt(encrypted, bob_private_jwk)\n```\n\n_Erlang_\n\n```erlang\n% RSA examples\nRSAPrivateJWK = jose_jwk:from_pem_file(\"rsa-2048.pem\"),\nRSAPublicJWK  = jose_jwk:to_public(RSAPrivateJWK).\n\n%% Sign and Verify (defaults to PS256)\nMessage = \u003c\u003c\"my message\"\u003e\u003e,\nSignedPS256 = jose_jwk:sign(Message, RSAPrivateJWK),\n{true, Message, _} = jose_jwk:verify(SignedPS256, RSAPublicJWK).\n\n%% Sign and Verify (specify RS256)\nSignedRS256 = jose_jwk:sign(Message, #{ \u003c\u003c\"alg\"\u003e\u003e =\u003e \u003c\u003c\"RS256\"\u003e\u003e }, RSAPrivateJWK),\n{true, Message, _} = jose_jwk:verify(SignedRS256, RSAPublicJWK).\n\n%% Encrypt and Decrypt (defaults to RSA-OAEP with A128CBC-HS256)\nPlainText = \u003c\u003c\"my plain text\"\u003e\u003e,\nEncryptedRSAOAEP = jose_jwk:block_encrypt(PlainText, RSAPublicJWK),\n{PlainText, _} = jose_jwk:block_decrypt(EncryptedRSAOAEP, RSAPrivateJWK).\n\n%% Encrypt and Decrypt (specify RSA-OAEP-256 with A128GCM)\nEncryptedRSAOAEP256 = jose_jwk:block_encrypt(PlainText, #{ \u003c\u003c\"alg\"\u003e\u003e =\u003e \u003c\u003c\"RSA-OAEP-256\"\u003e\u003e, \u003c\u003c\"enc\"\u003e\u003e =\u003e \u003c\u003c\"A128GCM\"\u003e\u003e }, RSAPublicJWK),\n{PlainText, _} = jose_jwk:block_decrypt(EncryptedRSAOAEP256, RSAPrivateJWK).\n\n% EC examples\nAlicePrivateJWK = jose_jwk:from_pem_file(\"ec-secp256r1-alice.pem\"),\nAlicePublicJWK  = jose_jwk:to_public(AlicePrivateJWK),\nBobPrivateJWK   = jose_jwk:from_pem_file(\"ec-secp256r1-bob.pem\"),\nBobPublicJWK    = jose_jwk:to_public(BobPrivateJWK).\n\n%% Sign and Verify (defaults to ES256)\nMessage = \u003c\u003c\"my message\"\u003e\u003e,\nSignedES256 = jose_jwk:sign(Message, AlicePrivateJWK),\n{true, Message, _} = jose_jwk:verify(SignedES256, AlicePublicJWK).\n\n%% Encrypt and Decrypt (defaults to ECDH-ES with A128GCM)\n%%% Alice sends Bob a secret message using Bob's public key and Alice's private key\nAliceToBob = \u003c\u003c\"For Bob's eyes only.\"\u003e\u003e,\nEncryptedECDHES = jose_jwk:box_encrypt(AliceToBob, BobPublicJWK, AlicePrivateJWK),\n%%% Only Bob can decrypt the message using his private key (Alice's public key is embedded in the JWE header)\n{AliceToBob, _} = jose_jwk:box_decrypt(EncryptedECDHES, BobPrivateJWK).\n```\n\n## Algorithm Support\n\n### JSON Web Encryption (JWE) [RFC 7516](https://tools.ietf.org/html/rfc7516)\n\n#### `\"alg\"` [RFC 7518 Section 4](https://tools.ietf.org/html/rfc7518#section-4)\n\n- [X] `A128GCMKW`\n- [X] `A192GCMKW`\n- [X] `A256GCMKW`\n- [X] `A128KW`\n- [X] `A192KW`\n- [X] `A256KW`\n- [X] `C20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n- [X] `dir`\n- [X] `ECDH-1PU` \u003csup\u003e[draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A128GCMKW` \u003csup\u003enon-standard, [draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A192GCMKW` \u003csup\u003enon-standard, [draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A256GCMKW` \u003csup\u003enon-standard, [draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A128KW` \u003csup\u003e[draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A192KW` \u003csup\u003e[draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+A256KW` \u003csup\u003e[draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+C20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02), [draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-1PU+XC20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02), [draft-madden-jose-ecdh-1pu](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04)\u003c/sup\u003e\n- [X] `ECDH-ES`\n- [X] `ECDH-ES+A128GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `ECDH-ES+A192GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `ECDH-ES+A256GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `ECDH-ES+A128KW`\n- [X] `ECDH-ES+A192KW`\n- [X] `ECDH-ES+A256KW`\n- [X] `ECDH-ES+C20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n- [X] `ECDH-ES+XC20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n- [X] `ECDH-SS` \u003csup\u003e[draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A128GCMKW` \u003csup\u003enon-standard, [draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A192GCMKW` \u003csup\u003enon-standard, [draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A256GCMKW` \u003csup\u003enon-standard, [draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A128KW` \u003csup\u003e[draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A192KW` \u003csup\u003e[draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+A256KW` \u003csup\u003e[draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+C20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02), [draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `ECDH-SS+XC20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02), [draft-amringer-jose-ecdh-ss](https://datatracker.ietf.org/doc/html/draft-amringer-jose-ecdh-ss-00)\u003c/sup\u003e\n- [X] `PBES2-HS256+A128GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `PBES2-HS384+A192GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `PBES2-HS512+A256GCMKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `PBES2-HS256+A128KW`\n- [X] `PBES2-HS384+A192KW`\n- [X] `PBES2-HS512+A256KW`\n- [X] `PBES2-HS512+C20PKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `PBES2-HS512+XC20PKW` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `RSA1_5`\n- [X] `RSA-OAEP`\n- [X] `RSA-OAEP-256`\n- [X] `XC20PKW` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n\n#### `\"enc\"` [RFC 7518 Section 5](https://tools.ietf.org/html/rfc7518#section-5)\n\n- [X] `A128CBC-HS256`\n- [X] `A192CBC-HS384`\n- [X] `A256CBC-HS512`\n- [X] `A128GCM`\n- [X] `A192GCM`\n- [X] `A256GCM`\n- [X] `C20P` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n- [X] `XC20P` \u003csup\u003e[draft-amringer-jose-chacha](https://datatracker.ietf.org/doc/html/draft-amringer-jose-chacha-02)\u003c/sup\u003e\n\n#### `\"zip\"` [RFC 7518 Section 7.3](https://tools.ietf.org/html/rfc7518#section-7.3)\n\n- [X] `DEF`\n\n### JSON Web Key (JWK) [RFC 7517](https://tools.ietf.org/html/rfc7517)\n\n#### `\"alg\"` [RFC 7518 Section 6](https://tools.ietf.org/html/rfc7518#section-6)\n\n- [X] `EC`\n- [X] `oct`\n- [X] `OKP` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"Ed25519\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.1)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"Ed25519ph\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.1)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"Ed448\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.2)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"Ed448ph\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.2)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"X25519\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 7748](https://tools.ietf.org/html/rfc7748#section-5)\u003c/sup\u003e\n- [X] `OKP` with `{\"crv\":\"X448\"}` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 7748](https://tools.ietf.org/html/rfc7748#section-5)\u003c/sup\u003e\n- [X] `RSA`\n\n### JSON Web Signature (JWS) [RFC 7515](https://tools.ietf.org/html/rfc7515)\n\n#### `\"alg\"` [RFC 7518 Section 3](https://tools.ietf.org/html/rfc7518#section-3)\n\n- [X] `Ed25519` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.1)\u003c/sup\u003e\n- [X] `Ed25519ph` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.1)\u003c/sup\u003e\n- [X] `Ed448` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.2)\u003c/sup\u003e\n- [X] `Ed448ph` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032#section-5.2)\u003c/sup\u003e\n- [X] `EdDSA` \u003csup\u003e[RFC 8037](https://tools.ietf.org/html/rfc8037), [RFC 8032](https://tools.ietf.org/html/rfc8032)\u003c/sup\u003e\n- [X] `ES256K` \u003csup\u003e[RFC 8812](https://datatracker.ietf.org/doc/html/rfc8812)\u003c/sup\u003e\n- [X] `ES256`\n- [X] `ES384`\n- [X] `ES512`\n- [X] `HS256`\n- [X] `HS384`\n- [X] `HS512`\n- [X] `Poly1305` \u003csup\u003enon-standard\u003c/sup\u003e\n- [X] `PS256`\n- [X] `PS384`\n- [X] `PS512`\n- [X] `RS1` \u003csup\u003edeprecated, [RFC 8812](https://datatracker.ietf.org/doc/html/rfc8812)\u003c/sup\u003e\n- [X] `RS256`\n- [X] `RS384`\n- [X] `RS512`\n- [X] `none` \u003csup\u003e[unsecured](#footnote-unsecured)\u003c/sup\u003e\n\n### Additional Specifications\n\n- [X] JSON Web Key (JWK) Thumbprint [RFC 7638](https://tools.ietf.org/html/rfc7638)\n- [X] JWS Unencoded Payload Option [RFC 7797](https://tools.ietf.org/html/rfc7797)\n\n\u003csup\u003e\u003ca name=\"footnote-unsecured\"\u003eunsecured\u003c/a\u003e\u003c/sup\u003e This algorithm is disabled by default due to the unsecured signing vulnerability.  Use the [`unsecured_signing`](#unsecured-signing-vulnerability) setting to enable this algorithm.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpotatosalad%2Ferlang-jose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpotatosalad%2Ferlang-jose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpotatosalad%2Ferlang-jose/lists"}