<!--
     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