Skip to content

Instantly share code, notes, and snippets.

@panva

panva/readme.md Secret

Created March 5, 2022 19:18
Show Gist options
  • Save panva/a085be6472d1c05af67d3e5f8dd17465 to your computer and use it in GitHub Desktop.
Save panva/a085be6472d1c05af67d3e5f8dd17465 to your computer and use it in GitHub Desktop.

How to select a JOSE / JWT cryptographic algorithm for your application

The need to secure tokens comes from a number concerns, any of which may apply to your particular use case:

  • Integrity: Verify token has not been tampered with
  • Authenticity: The origin of the token can be verified
  • Non-repudiation: The origin of the token must be verifiable by other parties
  • Confidentiality: Token payload is kept secret from unauthorized parties

Understanding which security aspect(s) we're after is the first step in selecting an appropriate JOSE algorithm.

This guide is in large inspired by c2id nimbus-jose-jwt which its authors have graciously allowed me to gather copies and content from.

Available JOSE algorithm classes

Integrity Authenticity Non-repudiation Confidentiality
HMAC
Digital signatures
Authenticated encryption

HMAC algorithms: An efficient hash (HMAC) for ensuring the integrity and authenticity of data. In order to compute an HMAC you need a secret key.

Digital signatures: Offers the properties of HMAC, plus cryptographic non-repudiation (enabling others than the signer to check the signature's validity). Digital signatures are based on public / private key cryptography. Require a public / private key pair (of type RSA, elliptic curve (EC), or Edwards-curve Octet Key Pair (OKP)).

Authenticated encryption: Encrypt data, while also ensuring its integrity and authenticity (like HMAC). JOSE offers encryption with recipient's public keys, with secret (shared) keys, and with passwords.

HMAC

Key type: Symmetric Secret keys (oct) Algorithms: HS256, HS384, HS512

Use when you're both the issuer and recipient of the token. E.g. when you want to sign your cookie values.

Notes:

  • The HMAC is not a digital signature.
  • Secrets shorter than the hash size are forbidden by the specification.
  • Secrets longer than the hash size don't provide additional security.
  • Payloads protected by HMAC are NOT encrypted, they're just encoded to be URL safe.

Digital Signatures

Key type: Public / Private key pairs (RSA, EC, OKP) Algorithms:

  • RSA signature with PKCS #1 and SHA-2: RS256, RS384, RS512
  • RSA PSS signature with SHA-2: PS256, PS384, PS512
  • ECDSA signature with SHA-2: ES256, ES256K, ES384, ES512
  • Edwards-curve DSA: EdDSA

Use when producing tokens, statements, assertions and documents which integrity and authenticity must be verifiable by third parties. E.g. access tokens, identity tokens, proofs of key possession.

Notes:

  • The signature is computed with a private key, which must be kept private at all times.
  • The signature of a JWT or JWS is validated with the public key, which is free to be distributed to the token's recipients.
  • Payloads protected by Digital signatures are NOT encrypted, they're just encoded to be URL safe.
  • RSA keys of less than 2048 bits are forbidden by the specification.
  • Algorithms have varying sign/verify throughput, RSA-based depend on the chosen key size, ECDSA and EdDSA depend on the key's curve.

Authenticated Encryption

Key type: Public / Private key pairs (RSA, EC, OKP), Symmetric Secret keys (oct) or Passwords Algorithms:

  • RSA key pair encryption algorithms: RSA-OAEP, RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512, RSA1_5
  • EC key pair encryption algorithms using ECDH: ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
  • OKP key pair encryption algorithms using ECDH: ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
  • Direct Encryption using a shared secret: dir
  • AES key wrap using a shared secret: A128KW, A192KW, A256KW
  • AES GCM key encryption using a shared secret: A128GCMKW, A192GCMKW, A256GCMKW
  • Password based encryption: PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW

Encrypt using a symmetric secret in case you encrypt data for yourself. Encrypt using the recipient's public key when you want the token payloads to remain confidential. Recipients will decrypt using their private key. Use a password based scheme when encrypting data with a rememberable passphrase.

Notes:

  • With the exception of "dir" all JWEs encrypt their payloads with a random content encryption key which is managed using the algorithms ("alg") described above. The payload encryption ("enc") is always AES based (either in CBC or GCM mode, when CBC is used SHA-2 is used to compute an authentication tag).
  • JWE payloads can be anything, e.g. a JWT or JWS token, this is called a Nested JWT.
  • Encrypting an HMAC JWS/JWT is redundant, use encryption with a symmetric secret instead. Either direct or key wrap based.
  • Do not use Public/Private key pair schemes when you're both the issuer and recipient, better use direct symmetric encryption in such case.
  • RSA keys of less than 2048 bits are forbidden by the specification.
  • Encryption in JOSE is always authenticated.

Nested signing and encryption

A signed JWT / JWS object can be additionally encrypted, thus providing integrity, authenticity, non-repudiation and confidentiality to data.

This is achieved by nesting (see #112).
To produce: The JWT is signed with a private RSA, EC or OKP key. The signed JWT then becomes the payload (plaintext) of a JWE object, which is encrypted with either the public key (RSA, EC, OKP) of the recipient, or with a secret key that has been shared between the two parties.
To consume: The JWE object is decrypted with the appropriate key (private key for RSA, EC or OKP, or established secret key). The extracted payload (plaintext) is then parsed as a signed JWT, and verified with the issuer's public key (RSA, EC or OKP).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment