<!-- Paragon Initiative Enterprises, LLC. URL: https://paragonie.com/b/EUD7cFYsOuddwAjy Format: Markdown Created: 2021-08-03T01:39:53+00:00 Modified: 2021-08-03T10:49:00+00:00 Accessed: 2025-05-02T10:21:52+00:00 --> When we designed [PASETO](https://paragonie.com/blog/2021/08/paseto-is-even-more-secure-alternative-jose-standards-jwt-etc), our goal was to provide an easy-to-use, secure-by-default, and simple protocol that solves the same sort of problems as [JSON Web Tokens](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid) (except *actually* secure). This resulted in two types of PASETO token being defined for each version of the protocol: 1. Local tokens: Symmetric authenticated encryption 2. Public tokens: Asymmetric digital signatures This solved [the majority of use cases](https://blog.ircmaxell.com/2014/10/an-open-letter-to-php-fig.html), but not all: If you wanted to use public-key encryption instead of symmetric-key encryption, you couldn't accomplish that with PASETO. Put flatly, there was no [JWK-equivalent for PASETO](https://github.com/paragonie/paseto/issues/88). With that in mind, today we'd like to announce the first PASETO extension: ## Platform-Agnostic SERializd Keys (PASERK) [PASERK](https://github.com/paseto-standard/paserk) provides the key-wrapping and serialization features missing from PASETO (which we excluded from PASETO to keep code sizes and complexity small; nobody wants to implement a standard that includes everything including the kitchen sink). Serialized PASETO keys are always in the format k[version_number].[type].[payload] The version number in a PASERK must match the protocol version number of the corresponding PASETO token. Additionally, each PASERK type encodes a key that can only be used with a specific PASETO purpose. Although we haven't declared the PASERK specification final yet, we do have a [reference implementation in PHP](https://github.com/paragonie/paserk-php) available. **Don't deploy PASERK in production until we tag `v1.0.0`.** ### Key Serialization The most obvious feature of PASERK is the ability to unambiguously encode PASETO keys. <table class="table"> <thead> <tr><th>PASERK Type</th><th>Meaning</th><th>PASETO Compatibility</th></tr> </thead> <tbody> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/local.md">local</a></td> <td>Symmetric key for <code>local</code> tokens.</td> <td><code>local</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/public.md">public</a></td> <td>Public key for verifying <code>public</code> tokens.</td> <td><code>public</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/secret.md">secret</a></td> <td>Secret key for verifying <code>secret</code> tokens.</td> <td><code>public</code></td> </tr> </tbody> </table> #### Key Serialization Examples k4.local.cHFyc3R1dnd4eXp7fH1-f4CBgoOEhYaHiImKi4yNjo8 k4.public.cHFyc3R1dnd4eXp7fH1-f4CBgoOEhYaHiImKi4yNjpA k4.secret.cHFyc3R1dnd4eXp7fH1-f4CBgoOEhYaHiImKi4yNjo8c5WpIyC_5kWKhS8VEYSZ05dYfuTF-ZdQFV4D9vLTcNQ ### Key Wrapping PASERK allows you to wrap symmetric keys (for `local` tokens) and asymmetric secret keys (for `public` tokens) with a symmetric key. <table class="table"> <thead> <tr><th>PASERK Type</th><th>Meaning</th><th>PASETO Compatibility</th></tr> </thead> <tbody> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/local-wrap.md">local-wrap</a></td> <td>Symmetric key wrapped by another symmetric key.</td> <td><code>local</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/secret-wrap.md">secret-wrap</a></td> <td>Asymmetric secret key wrapped by another symmetric key.</td> <td><code>public</code></td> </tr> </tbody> </table> PASERK key-wrapping is intentionally designed to allow vendors to [specify their own key-wrapping procedures](https://github.com/paseto-standard/paserk/blob/master/operations/Wrap.md#custom-key-wrapping-protocol-guidelines), provided they reserve a unique identifier in the PASERK specification (to ensure interoperability). We hope this makes PASERK useful for integrating with cryptographic material management services. However, we also provide [a standard implementation out-of-the-box](https://github.com/paseto-standard/paserk/blob/master/operations/Wrap/pie.md). #### Key-Wrapping Examples k4.secret-wrap.pie.7W3QNfBlWJOv-ZpAj21_-zL_FoeF_7fLxMyZWEFM2wluA0at6zhGosy0wYnXIXVtvODGO78dT3-fyKUPxYEpVMFoL9oX8dBtOzMxnfdC7e4hQPw_si8sMLlMjeQvgixK6y9ObKbFzPpaeA3NiJ3_c5PmkS2Kg6SYdeSvlAaJXY0 k4.secret-wrap.pie.jLhVAJYWaOcKiFvnKv6kFEQxSGV9BQuW1Qt4jRwr6yHiNeQf2h1GQ0czBJZpveX5T0R0YZv2OEenf8uyLqwamDJUbtS-GdYp_TXT1OJCwGJb2UpEHvcSOciH2PVCEiTrLM9n_mAI4SWXDfw4xYenmINDhi8EiPaPKvsOU64YBvY ### Public-Key Encryption PASERK allows you to use public-key encryption to wrap ephemeral symmetric keys, which you can in turn use with local PASETO tokens. <table class="table"> <thead> <tr><th>PASERK Type</th><th>Meaning</th><th>PASETO Compatibility</th></tr> </thead> <tbody> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/seal.md">seal</a></td> <td>Symmetric key wrapped using asymmetric encryption.</td> <td><code>local</code></td> </tr> </tbody> </table> #### Public-Key Encryption Example k4.seal.OPFn-AEUsKUWtAUZrutVvd9YaZ4CmV4_lk6ii8N72l5gTnl8RlL_zRFqWTZZV9gSnPzARQ_QklrZ2Qs6cJGKOENNOnsDXL5haXcr-QbTXgoLVBvT4ruJ8MdjWXGRTVc9 ### Password-Based Key-Wrapping Want to protect a PASETO key with a password? PASERK lets you do that too. <table class="table"> <thead> <tr><th>PASERK Type</th><th>Meaning</th><th>PASETO Compatibility</th></tr> </thead> <tbody> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/local-pw.md">local-pw</a></td> <td>Symmetric key wrapped using password-based encryption.</td> <td><code>local</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/secret-pw.md">secret-pw</a></td> <td>Asymmetric secret key wrapped using password-based encryption.</td> <td><code>public</code></td> </tr> </tbody> </table> #### Password-Based Key Wrapping Examples k4.local-pw._bru5tnkPSFXOtKhBTmW4gAAAAAEAAAAAAAAAgAAAAGKI3PyFS2vyQ9o5qowCR_GUXskLmdV1bjjc3vqnbwN7hVG1lAUCGjElTGIoH-K6lnkHnP4uaFBKWEtB3xFEGzAjzBSnl_JBmwLYK5jstjAV6LnJm_NOt0j k4.secret-pw.P9TfOO2cQALHf6zR_ztWLQAAAAAEAAAAAAAAAgAAAAEXfZr9S7Fv_j6onvrpEEyynt83OiH-q9pgT0eW9vgvUFevooP7dP13g51HQmNMT_5y9-sJCw5VCqfMnXHoOppw5Zu98ZQxEZXuIbbqQdc4MWS99uA3J63k2vSsy8_gUUQV1sStrO4fxVs-OWsl4oxVdRGFfF0bhLI ### Universally Unique Key Identifiers Finally, PASETO offers a unique and unambiguous way to calculate Key IDs from a given PASETO key. <table class="table"> <thead> <tr><th>PASERK Type</th><th>Meaning</th><th>PASETO Compatibility</th></tr> </thead> <tbody> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/lid.md">lid</a></td> <td>Unique Identifier for a separate PASERK for <code>local</code> PASETOs.</td> <td><code>local</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/pid.md">pid</a></td> <td>Unique Identifier for a separate PASERK for <code>public</code> PASETOs. (Public Key)</td> <td><code>public</code></td> </tr> <tr> <td><a href="https://github.com/paseto-standard/paserk/blob/master/types/sid.md">sid</a></td> <td>Unique Identifier for a separate PASERK for <code>public</code> PASETOs. (Secret Key)</td> <td><code>public</code></td> </tr> </tbody> </table> #### Key Identification Examples k4.lid.iVtYQDjr5gEijCSjJC3fQaJm7nCeQSeaty0Jixy8dbsk k4.pid.9ShR3xc8-qVJ_di0tc9nx0IDIqbatdeM2mqLFBJsKRHs k4.sid.gHYyx8y5YzqKEZeYoMDqUOKejdSnY_AWhYZiSCMjR1V5