Three years ago, we [introduced PASETO to the Internet](https://paragonie.com/blog/2018/03/paseto-platform-agnostic-security-tokens-is-secure-alternative-jose-standards-jwt-etc), as an alternative to the [insecure JOSE standards](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid). PASETO was designed with the philosophy of [avoiding in-band negotiation](https://paragonie.com/blog/2019/10/against-agility-in-cryptography-protocols), as well as recognizing that any cryptography key [should always be considered to be the raw key material alongside its parameter choices](https://twitter.com/SchmiegSophie/status/1264567198091079681). To that end, PASETO was built with **versioned protocols** at its foundation (and each key could only be used with a given **version** and **purpose**). Today, we announce the next iteration of the [PASETO specification](https://github.com/paseto-standard/paseto-spec), which includes two new protocols (Version 3 and Version 4). * [Version 3](https://github.com/paseto-standard/paseto-spec/tree/master/docs/01-Protocol-Versions#version-3-nist-modern) (if you need NIST-approved algorithms) * Local tokens (`v3.local`) use AES-256-CTR + HMAC-SHA384 (Encrypt-then-MAC) * Public tokens (`v3.public`) use ECDSA over NIST P-384 * [Version 4](https://github.com/paseto-standard/paseto-spec/tree/master/docs/01-Protocol-Versions#version-4-sodium-modern) (**Recommended**) * Local tokens (`v4.local`) use XChaCha20 + BLAKE2b-MAC (Encrypt-then-MAC) * This is very similar to what [Halite](https://github.com/paragonie/halite) has always done. * Public tokens (`v4.public`) use Ed25519. Security teams will mostly be interested in the [Rationale page in the PASETO Specification repository](https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md). Pay special attention to [the section on ECDSA security](https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md#ecdsa-security) and [questions for security auditors](https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md#questions-for-security-auditors). ## How the New PASETO Versions Improve Security PASETO Versions 3 and 4 aren't just new cryptography algorithm suites, they're a carefully engineered construction of deliberate cryptographic building blocks. Please refer to [the PASETO specification](https://github.com/paseto-standard/paseto-spec) (or the [v2.0.0 release notes for the Reference Implementation](https://github.com/paragonie/paseto/releases/tag/v2.0.0)) for the technical details on the *how*; we're going to talk about what the new versions give you.

Higher Limits on Symmetric-Key Reuse

A symmetric key in both PASETO versions can safely be reused for **up to $2^{112}$ tokens** before you'll need to rotate to a new key. **This is simply an unattainable number.** You can think of it as **infinite** for all practical purposes. Anyone capable of minting that many PASETO tokens under a single key is also capable of completely breaking Triple-DES and 2048-bit RSA without a quantum computer. #### How Is This Figure Calculated? The [birthday bound](https://en.wikipedia.org/wiki/Birthday_problem#Calculating_the_probability) for a 256-bit salt is $2^{128}$ (for a 50% chance of a single collision occurring). Setting the safety threshold to $2^{-32}$ (which is roughly a 1 in 4 billion chance) rather than merely 1/2 for a space of $2^{256}$ yields $2^{112}$ tokens before rotation is necessary.

Implicit Assertions

New to versions 3 and 4, PASETO supports a new feature called **Implicit Assertions**, which is unencrypted but authenticated data (like the optional footer), but is **NOT** stored in the PASETO token (thus, *implicit*) and **MUST** be asserted when verifying a token. The main purpose for Implicit Assertions is to bind the token to some value that, due to business reasons, shouldn't ever be revealed publicly (i.e., a primary key or foreign key from a relational database table). Implicit Assertions allow you to build systems that are impervious to [Confused Deputy attacks](https://cloud.google.com/kms/docs/additional-authenticated-data#confused_deputy_attack_example) without ever having to disclose these internal values.

Exclusive Ownership

Out of the box, RSA and ECDSA signatures do not provide a property known as [Exclusive Ownership](https://www.bolet.org/~pornin/2005-acns-pornin+stern.pdf) (PDF), which means that only a given public key could have produced the signature for a given message. This isn't usually relevant to the security of web applications (n.b., people use digital signatures that prove a message is authentic, given a specific public key), unless you're building something like a consensus protocol where the signature should only be possible from a single given asymmetric keypair. Version 1 in `public` mode, however, did not fulfill this property. The fix for this is twofold: 1. Use a collision-resistant cryptographic hash function (which you already should be). 2. Include the public key in the message being signed. Interestingly, EdDSA already hashes the public key with the message, so this attack would never work against Ed25519 (although [a related attack works on older implementations](https://github.com/jedisct1/libsodium/issues/112) that omit a malleability check). Since we're using a relatively recent version of libsodium in most places, we didn't even have to care about this property in Version 2 or 4. Both of the new versions fulfill this property (called **Universal Exclusive Ownership**, as specified in Section 3.3 of the PDF linked above), so if you wanted to use PASETO for some interesting high-level protocols, you're better served by the new versions than the original.

Random-Key Robustness

AEAD modes based on Polynomial MACs, such as AES-GCM and XChaCha20-Poly1305, do not offer [message- or key-commitment](https://eprint.iacr.org/2019/016). This means it's possible to construct two different plaintexts that, under two different keys, yield the same (nonce, ciphertext, tag) tuple. This means that a given PASETO v2 token might decode to two different payloads, under two different keys. Consequently, PASETO Version 4 does away with Poly1305 for Local tokens. Instead, it uses BLAKE2b-MAC (see also: [sodium_crypto_generichash()](https://www.php.net/sodium_crypto_generichash) when a key is specified), which provides resilience against this unexpected behavior. ## Comparing PASETO v3/v4 with the JOSE Standards The earlier versions of PASETO already offered significant security benefits over [the JOSE standards](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid); particularly, JSON Web Signatures and JSON Web Encryption. These new versions provide additional security benefits without compromising the original premises of PASETO: * Only allow one suite of cryptographic algorithms for a given version and purpose * Only allow a cryptography key to be used for a single version and purpose * Turn security up to 11 without harming usability (because if we did, per Avi Douglen's Law, it would harm security) Despite the additional security benefits of the new versions, their descriptions are comparable to the original in terms of implementation complexity. (Contrast [Version 2](https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Version2.md) with [Version 4](https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Version4.md) if you need a visual example.) However, there were a couple of use-cases not addressed by PASETO: Key-wrapping, public-key encryption, unambiguous serialization, and providing universally unique key identifiers. To remedy that, we've begun specifying [a PASETO extension called *PASERK* (Platform-Agnostic SERialized Keys)](https://paragonie.com/blog/2021/08/introducing-paserk-first-paseto-extension-for-key-wrapping-and-serialization), which is our answer to JOSE's JWK specification.