Home

Awesome

PASERK: Platform-Agnostic Serialized Keys

PASERK is an extension to PASETO that provides key-wrapping and serialization.

Motivation

PASETO provides two types of tokens (called a purpose) in each of its versions:

PurposeCryptographic Operation
localSymmetric-key authenticated encryption with additional data (AEAD)
publicAsymmetric-key digital signatures (no encryption)

These two token modes solve at least 80% of use cases for secure tokens. You can even solve unencrypted symmetric-key authentication by storing your claims in the unencrypted footer, rather than encrypting them.

The use-cases that PASETO doesn't address out of the box are:

PASERK aims to provide an answer for these circumstances, as well as provide a consistent standard for the encoding of PASETO keys.

PASERK

A serialized key in PASERK has the format:

k[version].[type].[data]

Where [version] is an integer, [data] is the (typically base64url-encoded) payload data, and [type] is one of the items in the following table:

PASERK TypeMeaningPASETO Compatibility[data] Encoded?Safe in Footer?
lidUnique Identifier for a separate PASERK for local PASETOs.localYesYes
localSymmetric key for local tokens.localYesNo
sealSymmetric key wrapped using asymmetric encryption.localYesYes
local-wrapSymmetric key wrapped by another symmetric key.localNoYes
local-pwSymmetric key wrapped using password-based encryption.localYesNo
sidUnique Identifier for a separate PASERK for public PASETOs. (Secret Key)publicYesYes
publicPublic key for verifying public tokens.publicYesNo
pidUnique Identifier for a separate PASERK for public PASETOs. (Public Key)publicYesYes
secretSecret key for signing public tokens.publicYesNo
secret-wrapAsymmetric secret key wrapped by another symmetric key.publicNoYes
secret-pwAsymmetric secret key wrapped using password-based encryption.publicYesNo

The version of a PASERK MUST match the version of the PASETO it's used with. For example, a k2.local. PASERK must be used with v2.local. tokens. Cross-version support is explicitly NOT permitted.

Each type is a composition of one or more operations.

As one of the design criteria, it MUST be safe for users to store the ID PASERK for a PASETO key (resulting in lid, sid, or pid types) in the footer (or, in v3/v4 of PASETO, as an implicit assertion). These types SHOULD be stored in the kid field in the footer, if the footer is JSON encoded.

Any of these PASERK types MAY be stored in the PASETO footer (in the wpk claim), because the encoded key is also wrapped with additional layers of cryptography: local-wrap, seal, secret-wrap. The wrapping key MUST NOT be disclosed.

All other types MUST NOT be included in a PASETO footer.

Examples of Valid PASERKs in a PASETO Footer

{"kid":"k4.lid.iVtYQDjr5gEijCSjJC3fQaJm7nCeQSeaty0Jixy8dbsk"}
{"kid":"k4.pid.9ShR3xc8-qVJ_di0tc9nx0IDIqbatdeM2mqLFBJsKRHs"}
{"kid":"k4.sid.gHYyx8y5YzqKEZeYoMDqUOKejdSnY_AWhYZiSCMjR1V5"}

The PASERK key ID is always okay to include in a PASETO footer.


{"wpk":"k4.local-wrap.pie.pu-fBxwoXrICYjeumh77cJ6la4svNGrjshQ7W_ygiJzm80LQBB1e6yqODDq6HO8c0UNY_dzLkzZC62Z81eleoIYUChwymEx23KbTQDinWaOQoKkRantNkrD5o0eo8iCS"}
{"wpk":"k4.secret-wrap.pie.jLhVAJYWaOcKiFvnKv6kFEQxSGV9BQuW1Qt4jRwr6yHiNeQf2h1GQ0czBJZpveX5T0R0YZv2OEenf8uyLqwamDJUbtS-GdYp_TXT1OJCwGJb2UpEHvcSOciH2PVCEiTrLM9n_mAI4SWXDfw4xYenmINDhi8EiPaPKvsOU64YBvY"}

Wrapped keys are encrypted. As long as the wrapping key is confidential, this is safe.


{"wpk":"k4.seal.3-VOL4pX5b7eV3uMhYHfOhJNN77YyYtd7wYXrH9rRucKNmq0aO-6AWIFU4xOXUCBk0mzBZeWAPAKrvejqixqeRXm-MQXt8yFGHmM1RzpdJw80nabbyDIsNCpBwltU-uj"}

Sealed keys are wrapped using public-key encryption. As long as the unwrapping key (asymmetric secret key) is confidential, this is safe.

Examples of Invalid PASERKs in a PASETO Footer

{"wpk":"k4.local.cHFyc3R1dnd4eXp7fH1-f4CBgoOEhYaHiImKi4yNjo8"}

This is a local type, and it is forbidden. Critically, it would disclose a symmetric key if included in an unencrypted PASETO footer.

{"wpk":"k3.secret.cHFyc3R1dnd4eXp7fH1-f4CBgoOEhYaHiImKi4yNjo-QkZKTlJWWl5iZmpucnZ6f"}

This is a secret type, and it is forbidden. Critically, it would disclose an asymmetric secret key if included in an unencrypted PASETO footer.

{"wpk":"k3.public.AnBxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2enw"}

This is forbidden by the PASETO specification:

IMPORTANT: Key identifiers MUST be independent of the actual keys used by Paseto.

For example, you MUST NOT just drop the public key into the footer for a public token and have the recipient use the provided public key. Doing so would allow an attacker to simply replace the public key with one of their own choosing, which will cause the recipient to simply accept any signature for any message as valid, which defeats the security goals of public-key cryptography.

Instead, it's recommended that implementors and users use a unique identifier for each key (independent of the cryptographic key's contents itself) that is used in a database or other key-value store to select the apppropriate cryptographic key. These search operations MUST fail closed if no valid key is found for the given key identifier.

Even though a public key might seem harmless, it risks the encouragement of in-band negotiation. This could result in users trusting the attacker-provided public key associated with a PASETO, which would bypass the security offered by the security token. Therefore, this use case MUST NOT ever be permitted.


{"wpk":"k4.local-pw._bru5tnkPSFXOtKhBTmW4gAAAAAEAAAAAAAAAgAAAAGKI3PyFS2vyQ9o5qowCR_GUXskLmdV1bjjc3vqnbwN7hVG1lAUCGjElTGIoH-K6lnkHnP4uaFBKWEtB3xFEGzAjzBSnl_JBmwLYK5jstjAV6LnJm_NOt0j"}
{"wpk":"k4.secret-pw.dkyi7kfzHnVTCqTq1AvLyQAAAAAQAAAAAAAAAwAAAAFWNLgB_yXNkk4W9NiXgeTkNnB3Vjuk_-TFQ-vMUxNX-Ha3k42djov9rHVykMHkrSGUemYFwpot9uNHnXOWtJCVIwdYAwZmt_uRSJ2rRTElanT6mWXojuBUy2k1lxD-iZ10pVPkJ-Kvv_SLEhLQ8RS7wqFW8RfFGyw"}

Password-based key-wrapping is provided in PASERK for systems that need password-protected cryptographic secrets, but password-protected keys MUST NOT be included in a PASETO footer.

PASERK Implementations