PASETO: Platform-Agnostic Security Tokens

Overview

PASETO: Platform-Agnostic Security Tokens

Build Status Latest Stable Version Latest Unstable Version License Downloads

Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the many design deficits that plague the JOSE standards.

This library is a reference implementation of PASETO in the PHP language. Please refer to the PASETO Specification for design considerations.

How to Use this Library

See the documentation.

The PASETO specification may also be useful for understanding why things are designed the way they are.

Requirements

PHP PASETO Library Version 2

  • Requires PHP 7.1 or newer.
  • For v3 tokens, the GMP and OpenSSL extensions are required.
  • For v4 tokens, the Sodium extension is strongly recommended (but this library will use sodium_compat if it's not).

PHP PASETO Library Version 1

  • Requires PHP 7.0 or newer.
  • For v1 tokens, the OpenSSL extension is required.
  • For v2 tokens, the Sodium extension is strongly recommended (but this library will use sodium_compat if it's not).

Support Contracts

If your company uses this library in their products or services, you may be interested in purchasing a support contract from Paragon Initiative Enterprises.

Comments
  • Initial Draft for PASETO v3/v4 specifications

    Initial Draft for PASETO v3/v4 specifications

    No Code Changes; only specification

    See #128 for the implementation.

    (Copied from Rationale-V3-V4.md)

    Primary Motivations for New Versions

    v4.local

    v2.local was originally specified to use XChaCha20-Poly1305, a boring AEAD mode that's obviously secure. However, we've since learned about key- and message-commitment, which is an important security property in systems with multiple possible symmetric keys.

    Since PASETO added footers to support key-ids and key rotation strategies, this means we MUST take attacks that depend on random-key robustness seriously.

    PASETO v4.local uses XChaCha20 to encrypt the message, but then uses a keyed BLAKE2b hash (which acts as HMAC) for the authentication tag.

    v3.public

    We specified RSA for PASETO v1.public tokens, under the assumption that applications that must ONLY support NIST algorithms (e.g. because they MUST only use FIPS 140-2 validated modules to maintain compliance) would be adequately served by RSA signatures. This assumption turned out to be incorrect, and elliptic curve cryptography is now preferred.

    To better meet the needs of applications that are NIST-dependent, PASETO v3.public tokens will support ECDSA over NIST's P-384 curve, with SHA-384, and (preferably) using RFC 6979 deterministic signatures. (RFC 6979 is a SHOULD, not a MUST, due to library availability issues and fault attacks.)

    ECDSA Security

    ECDSA is much more dangerous to implement than Ed25519:

    1. You have to ensure the one-time secret k is never reused for different messages, or you leak your secret key.
    2. If you're not generating k deterministically, you have to take extra care to ensure your random number generator isn't biased. If you fail to ensure this, attackers can determine your secret key through lattice attacks.
    3. The computing k^-1 (mod p) must be constant-time to avoid leaking k.
      • Most bignum libraries DO NOT provide a constant-time modular inverse function, but cryptography libraries often do. This is something a security auditor will need to verify for each implementation.

    There are additional worries with ECDSA with different curves, but we side-step most of these problems by hard-coding one NIST curve and refusing to support any others. The outstanding problems are:

    There are additional protocol-level security concerns for ECDSA, namely:

    • Invalid Curve Attacks, which are known to break ECDH.
      • This is solved in PASETO through requiring support for Point Compression.
      • Implementations MAY also optionally support PEM encoding of uncompressed public key points, but if they do, they MUST validate that the public key is a point on the curve.
      • Point compression used to be patented, but it expired. It's high time we stopped avoiding its usage as an industry.
    • Exclusive Ownership. See below.

    Because of these concerns, we previously forbid any implementation of ECDSA without RFC 6979 deterministic k-values in a future version.

    However, given the real-world requirements of applications and systems that must comply with NIST guidance on cryptography algorithms, we've relaxed this requirement.

    Additionally, deterministic k-values make signers more susceptible to fault attacks than randomized signatures. If you're implementing PASETO signing in embedded devices, or environments where fault injection may be a practical risk, there are two things you can do:

    1. Don't use deterministic signatures because of your specific threat model.
    2. Hedged signatures: Inject additional randomness into the RFC 6979 step. This randomness doesn't need to be signed.

    Questions For Security Auditors

    Due to the risks inherent to ECDSA, security assessors should take care to cover the following questions in any review of a PASETO implementation that supports v3.public tokens (in addition to their own investigations).

    1. Is RFC 6979 supported and used by the implementation?
      1. If not, is a cryptographically secure random number generator used?
      2. If the answer to both questions is "No", fail.
    2. Is modular inversion (k^-1 (mod p)) constant-time?
      1. If not, fail.
    3. Are public keys expressed as compressed points?
      1. If not, is the public key explicitly validated to be on the correct curve (P-384)?
      2. If the answer to both questions is "No", fail.
    4. Does the underlying cryptography library use complete addition formulas for NIST P-384?
      1. If not, investigate how the library ensures that scalar multiplication is constant-time. (This affects the security of key generation.)

    Affirmative answers to these questions should provide assurance that the ECDSA implementation is safe to use with P-384, and security auditors can focus their attention on other topics of interest.

    v3.local / v4.public

    No specific changes were needed from (v1.local, v2.public) respectively. See below for some broader changes.

    Beneficial Changes to V3/V4

    No More Nonce-Hashing (Change)

    The initial motivation for hashing the random nonce with the message was to create an SIV-like construction to mitigate the consequences of weak random number generators, such as OpenSSL's (which isn't fork-safe).

    However, this creates an unfortunate failure mode: If your RNG fails, the resultant nonce is a hash of your message, which can be used to perform offline attacks on the plaintext. This was first discovered by Thái Dương.

    To avoid this failure mode, neither v3.local nor v4.local will pre-hash the message and random value to derive a nonce. Instead, it will trust the CSPRNG to be secure.

    Implicit Assertions (Feature)

    PASETO v3 and v4 tokens will support optional additional authenticated data that IS NOT stored in the token, but IS USED to calculate the authentication tag (local) or signature (public).

    These are called implicit assertions. These can be any application-specific data that must be provided when validating tokens, but isn't appropriate to store in the token itself (e.g. sensitive internal values).

    One example where implicit assertions might be desirable is ensuring that a PASETO is only used by a specific user in a multi-tenant system. Simply providing the user's account ID when minting and consuming PASETOs will bind the token to the desired context.

    Better Use of HKDF Salts (Change)

    With v1.local, half of the 32-byte random value was used as an HKDF salt and half was used as an AES-CTR nonce. This is tricky to analyze and didn't extend well for the v4.local proposal.

    For the sake of consistency and easy-to-analyze security designs, in both v3.local and v4.local, we now use the entire 32-byte random value in the HKDF step.

    Instead of being used as a salt, however, it will be appended to the info tag. This subtle change allows us to use the standard security definition for HKDF in arguments for PASETO's security, rather than treating it as just a pseudo-random function (PRF). This security definition requires only one salt to be used, but for many contexts (info tags).

    The nonce used by AES-256-CTR and XChaCha20 will be derived from the HKDF output (which is now 48 bytes for v3.local and 56 bytes for v4.local). The first 32 bytes of each HKDF output will be used as the key. The remaining bytes will be used as the nonce for the underlying cipher.

    Local PASETOs in v3 and v4 will always have a predictable storage size, and the security of these constructions is more obvious:

    • The probability space for either mode is 256-bits of randomness + 256-bits of key, for a total of 512 bits.
      • The HKDF output in v3.local is 384 bits.
      • The HKDF output in v4.local is 448 bits.
      • Neither of these output sizes reduces the security against collisions. (If they were larger than the input domain of 512 bits, that would be a blunder.)
    • A single key can be used for 2^112 PASETOs before rotation is necessary.
      • The birthday bound 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) for a space of 2^256 yields 2^112.
    • The actual nonce passed to AES-CTR and XChaCha is not revealed publicly.

    V3 Signatures Prove Exclusive Ownership (Enhancement)

    RSA and ECDSA signatures do not prove Exclusive Ownership. This is almost never a problem for most protocols, unless you expect this property to hold when it doesn't.

    Section 3.3 of the paper linked above describes how to achieve Universal Exclusive Ownership (UEO) without increasing the signature size: Always include the public key in the message that's being signed.

    Consequently, v3.public PASETOs will include the raw bytes of the public key in the PAE step for calculating signatures. The public key is always a compressed point (0x02 or 0x03, followed by the X coordinate, for a total of 49 bytes).

    We decided to use point compression in the construction of the tokens as a forcing function so that all PASETO implementations support compressed points (and don't just phone it in with PEM-encoded uncompressed points).

    Ed25519, by design, does not suffer from this, since Ed25519 already includes public key with the hash function when signing messages. Therefore, we can safely omit this extra step in v4.public tokens.

    Miscellaneous Changes

    Define Mechanism for Extending PASETO for non-JSON Encodings

    PASETO serializes its payload as a JSON string. Future documents MAY specify using PASETO with non-JSON encoding. When this happens, a suffix will be appended to the version tag when a non-JSON encoding rule is used.

    For example, a future PASETO-CBOR proposal might define its versions as v1c, v2c, v3c, and v4c. The underlying cryptography will be the same as v1, v2, v3, and v4 respectively. Keys SHOULD be portable across different underlying encodings, but tokens MUST NOT be transmutable between encodings without access to the symmetric key (local tokens) or secret key (public tokens).

    Questions and Answers

    Why Not AES-GCM in v3.local?

    While it's true that AES-GCM is more broadly supported in environments that use NIST and FIPS-approved cryptography, GMAC is neither message-committing nor key-committing.

    The techniques for turning an AEAD scheme into an AEAD scheme is well known, but it requires publishing an additional SHA2 hash (or KDF output) of the key being used.

    Using GCM would require us to also publish an additional hash anyway. At that point, it doesn't offer any clear advantage over CTR+HMAC.

    CTR+HMAC (with separate keys and PAE) is a secure construction and provides the cryptographic properties we need to use PASETO in threat models where multiple keys are used or partitioning oracles are possible.

    Why P-384 in v3.public instead of P-256 or P-521?

    Security experts that work heavily with NIST algorithms expressed a slight preference for P-384 over P-521 and P-256 when we asked. This is also congruent for our choice of SHA-384 as a hash function over SHA-256 or SHA-512.

    The security considerations for the NIST curves are mostly congruent (albeit the ECDLP security and performance differs a bit).

    If you want smaller tokens or better performance than P-384, make sure Ed25519 lands in FIPS 186-5 and use v4.public instead.

    opened by paragonie-security 49
  • Curate Other Implementations of Paseto

    Curate Other Implementations of Paseto

    Languages desired:

    • [x] C
    • [x] C# (.NET)
    • [x] Go
    • [x] Java
    • [x] Javascript
    • [ ] Perl
    • [x] Python
    • [x] Ruby
    • [x] Rust
    • [x] Swift
    • Feel free to suggest other languages too.
    help wanted good first issue 
    opened by paragonie-scott 14
  • RFC draft expired

    RFC draft expired

    https://tools.ietf.org/html/draft-paragon-paseto-rfc-00 notes: “Expires: October 21, 2018” No new draft seems to have been submitted yet. This may need updating.

    help wanted outreach on-roadmap 
    opened by xorhash 12
  • Payload key ordering

    Payload key ordering

    I couldn't find any information about what is the expected order of keys in the payload, it would be useful that in any implementation such code:

    encode(decode(Payload)) == Payload
    

    Currently from what I see there is nothing that ensures such behaviour. This could be achieved with #90 and usage of ASN.1 DER format for example, but right now standard requires payload to be correct Base64 encoded JSON token.

    question 
    opened by hauleth 11
  • Key objects / JWK equivalent

    Key objects / JWK equivalent

    For paseto to become a viable JOSE alternative, it probably needs to cover more of the JOSE suite including JWK.

    At DC26 CiPHPerCoder talked about how key objects in library implementations should be typed and not just byte arrays. To this end, paseto should have a JSON object format for keys to a) guide implementations of key classes and b) provide simple standard ways of serializing/deserializing keys.

    opened by nrktkt 11
  • `Parser` shouldn't produce signable `Builder`s?

    `Parser` shouldn't produce signable `Builder`s?

    In the 'public' case of: https://github.com/paragonie/paseto/blob/c44d33467662f23d3d6ef7ea22f8926333a8e763/src/Parser.php#L190-L220

    $this->key is checked to be an instance of AsymmetricPublicKey, which is later passed to JsonToken::setKey. However, this requires the given key to be an instance of AsymmetricSecretKey in the 'public' case. https://github.com/paragonie/paseto/blob/c44d33467662f23d3d6ef7ea22f8926333a8e763/src/JsonToken.php#L374-L382

    Obviously there's going to be a type mis-match here, but on a more general note:

    Given that the JsonToken is constructed with a key for signing, I don't think it would ever make sense to have the parser produce a JsonToken in the public case, because it would require knowledge of the secret key to sign, but the parser is only really concerned with verification which requires only the public key (which is likely all the receiver of a signed object has?).

    I think perhaps the key/signing should be decoupled from the JsonToken so that the parser can produce these objects without requiring a key, and the key should be provided when signing takes place (perhaps in a new SignableJsonToken class for example that is constructed using a JsonToken and a key).

    user-friendliness 
    opened by aidantwoods 10
  • PASETO RFC (First Draft)

    PASETO RFC (First Draft)

    Thanks @tarcieri for recommending mmark.

    To contribute to the RFC development.

    1. Clone the rfc branch.
    2. cd docs/RFC
    3. Make your changes in paseto.md
    4. Run the build.sh script.
    5. Commit changes to paseto.md. Committing changes to the .txt file is not necessary.
    6. Make a pull request against the rfc branch.

    Once we're happy with the first draft, I'll merge this and email it to the IETF.

    Closes #16

    opened by paragonie-scott 8
  • Paseto can be use is production ?

    Paseto can be use is production ?

    Hi,

    I just finish to read your post about JWT security issues. Now I need to plan to migrate my code from JWT to another solution.

    I saw you made 3 Pre-release, but you set your version 0.3.0 as stable. So I don't know if you consider PAST production ready.

    PAST isn't stable/secure enough to be use in production ?

    Thanks for your work ;)

    question documentation 
    opened by Ducatel 8
  • public payload isn't encrypted

    public payload isn't encrypted

    First, thanks for creating Paseto.

    I found it to be a really surprising aspect of Paseto that even though it's built on top of modern cryptographic libraries and is designed to be a secure replacement for JWT, it doesn't actually encrypt the data.

    This is something that someone can seriously shoot themselves in the foot, because it's not secure by default, and when I think about "public", I associate it with encrypted public key cryptography, e.g. GPG/SSH. Instead of "public" calling it "unencrypted-signed" would be a better name to highlight the danger of using it.

    This really limits the use cases of Paseto for, specifically any kind of server to server APIs which contains private/secret data, or semi-trusted server environments.

    Paseto gives 4 options, and none of them are secure by default

    v1.local and v1.public use outdated cryptography. I don't think anyone who is adopting Paseto will choose to use them. v2.local requires to share the private key v2.public doesn't encrypt the data (somewhat like alg: "none")

    I would think it would be much better to only have one option (v3), using encrypted public-key cryptography, and deprecate the other options. This would significantly simplify the standard, yet fulfill more use cases in a more secure manner. This is the approach taken by Branca.

    This gives you flexibility of either encrypting data in the payload, or just signing data in the footer, or a combination of both.

    libsodium is pretty much ubiquitous at this point, and v1 is not interoperable and thus fails to serve as a lowest common denominator, as many libraries don't support it.

    Regarding https://github.com/paragonie/paseto/issues/83#issuecomment-404942554 My understanding is encrypt+sign is not secure, as someone can replay the encrypted part. While sign+encrypt does not allow to have an unencrypted footer.

    I think the best approach would be to sign+encrypt+sign. i.e. sign the payload, encrypt it, and then sign the entire message, including the unencrypted footer.

    http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html#tth_sEc5.2

    opened by shaicoleman 7
  • extract php implementation and specification from the repository

    extract php implementation and specification from the repository

    Hello, I think for a readability of the project, it could be very helpfull to split the specification of paseto and the implementation in php. It allow people to see to evolution of the spec and the implemntation without any missmatch.

    thanks

    opened by Grummfy 7
  • Payload processing specification

    Payload processing specification

    Since there's no issue open specifically for this:

    Currently the documentation only goes so far as to specify the Paseto message format, but does not specify how to process this payload after decrypting or verifying it.

    From reading the reference implementation I can probably answer most of the following myself, the goal here is to highlight questions that the spec should answer if processing the payload is going to be part of the specification, it's not just a series of personal questions :p

    • [x] How payloads represented as strings should be encoded into bytes (utf8?)

    • [x] Is a JSON encoded payload part of the spec? Is it required that (received||sent) payloads are in this format, or optional?

    • [x] Specify the type (or even data) structure (if any) that the JSON payload should conform to~~o~~

      • Reference implementation appears to hint that this is array<string, string>, but I think it actually allows array<string, mixed> due to a type hint diverging with the doc block. See also probable need for type validation on bulk setting of claims.
    • [x] Are arbitrary keys allowed to be set? (or is there a reserved character set for example?)

    • [x] Are any keys reserved for certain purposes? (e.g. the ones used for rules like expiry)

    • [ ] Are these reservations case sensitive? (e.g. should an expiry key with incorrect case be ignored?)

    • [x] Should users be allowed to set reserved keys like arbitrary other keys, or should distinct mechanisms be enforced?

    • [ ] If users can set these, do we fail if the user puts unexpected (e.g. unparseable) data in these reserved fields (i.e. should writes to reserved fields be validated)?

    • [x] Are rules part of the spec? (if so what are they?)

    • [x] Are rules specified as reserved keys, or are they in a structurally different part of the JSON payload to user data?

    • [x] Is rule validation required? (if no, what should be the default?)

    • [ ] Do we fail open or closed if a rule is of an unexpected format?

    • [ ] Will payload processing receive spec updates (e.g. potential changes to rules, addition of rules), how should this be versioned?

    • [ ] If payload processing is versioned, where do we put this version?

    Can probably ask at least the encoding question for processing the footer too, though that seems really intended just to be a string.

    documentation 
    opened by aidantwoods 7
  • Cannot read pem created with encodePem

    Cannot read pem created with encodePem

    file_put_contents(__DIR__ . '/key.pem', AsymmetricSecretKey::generate(new Version4())->encodePem());
    SecretKey::importPem(file_get_contents(__DIR__ . '/key.pem'));
    

    The above throws a RuntimeException("Invalid data.") because $asnObject->getNumberofChildren() returns 3. Am I wrong to think that the above should work?

    opened by frederikbosch 0
Releases(v3.0.2)
  • v3.0.2(Jun 20, 2022)

  • v2.4.3(Jun 20, 2022)

  • v3.0.1(Jun 10, 2022)

    • Invalid base64 encoding of PASETO tokens is rejected. See https://github.com/paseto-standard/paseto-spec/issues/28 for the specification discussion.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(Jun 3, 2022)

    • Removed Version1 and Version 2 (which were deprecated earlier this year).
    • Minimum PHP Version: 8.1.0
    • Removed HKDF polyfill
    • Removed __toString() weirdness for PHP < 7.4
    • Lots of code clean-up; making use of the updated type system in PHP 8.1
    • Use Corner for more helpful exceptions.
    • Removed all hacks and annotations to make Psalm happy. Our code is now fully statically analyzed on every CI/CD push.
    Source code(tar.gz)
    Source code(zip)
  • v2.4.2(Jun 2, 2022)

  • v2.4.1(Apr 30, 2022)

    • #155 - Fixed minor nits (docblocks, exception propagations) discovered during routine code review.
    • Additionally, while not security-related: Encryption/MAC keys are now wiped as soon as possible in V1, V3, and V4.
      • V2 doesn't need this change.
    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(Apr 26, 2022)

    • #151 - Fixed IdentifiedBy to check jti claim
    • #152 - Docblocks allow mixed-value claims
    • #154 - Add isForVersion() helper to PASETO Key objects.
      • For example: $key->isForVersion(new Version4) will return true if the key is intended for PASETO v4, and false otherwise.
    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Jan 17, 2022)

    • PASETO v1 and v2 protocols are now deprecated, please use v3 and v4 in new code.
    • #147 - Removed dead code due to a previous optimization (Thanks @arokettu!)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Oct 27, 2021)

    • Added encodePem() to AsymmetricSecretKey and AsymmetricPublicKey.
    • The default behavior of AsymmetricSecretKey::encode() for Version3 is to return the base64url encoding of the secret scalar, not of the PEM-encoded string.
    • #145: Throw an exception if a message is too short
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(Sep 17, 2021)

  • v2.1.0(Sep 7, 2021)

    This is a feature release for the PHP implementation of PASETO.

    New Features

    • Unless otherwise specified by the user, expiration is enforced by default in both the Builder and Parser classes. You can disable this default by invoking ->setNonExpiring(true) on your Builder or Parser objects.
    • Added support for Key Rings. (#137)
    • Expanded unit tests to cover algorithm lucidity
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Aug 3, 2021)

    This is v2.0.0 of the PHP implementation of PASETO.

    At a glance:

    • This library now requires PHP 7.1 or newer.
    • This library now requires the GMP extension installed (due to an additional dependency).
    • The default protocol has been changed from Version2 to Version4. If you weren't defining this in your code and relying on the default settings, you will need to be explicit before you upgrade.

    A lot has changed; please read carefully.

    We've moved the PASETO Specification to another repository. In this updated specification, we have defined two new PASETO protocol versions.

    • Version 3 is the successor to Version 1 for systems that MUST only use NIST-approved algorithms.
    • Version 4 is the successor to Version 2 for systems that want to use the algorithms provided by libsodium over the choices made by NIST and/or the US National Security Agency.

    If you'd like to read the full rationale for the design decisions made in Versions 3 and 4, these have been documented clearly here.

    Although we strongly recommend migrating to the new versions (v1 -> v3, v2 -> v4), you are fine to continue using v1/v2 if the following assumptions hold true:

    • PHP's random_bytes() is working correctly (i.e. talking to the kernel's CSPRNG).
    • For v1.public tokens:
    • For v2.local tokens:
      • You will only use one key at a time, and attackers cannot switch between them (i.e. no Key IDs in the footer)

    If any of these assumptions are invalid, you MUST use the new versions to get the security properties you need out of PASETO. See the brief yet concise Migration Guide for more information.

    Questions and Answers

    What if I'm unsure if I should migrate to the newer version?

    If you aren't 100% sure you don't need the security properties offered by v3/v4, and have nothing preventing you from making the change (i.e. a hard dependency on RSA keys), then you should lean towards migrating.

    It's better to have it and not need it, than need it and not have it.

    Is PASETO v1/v2 vulnerable?

    Generally, no. That's why we aren't immediately deprecating their use. The complete answer requires a bit of nuance:

    • AEAD modes based on Polynomial MACs, such as AES-GCM and XChaCha20-Poly1305, do not offer message- or key-commitment. 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.

      • If you're using v2.local tokens with some sort of homemade key-wrapping scheme that doesn't provide key-commitment, then YES, you SHOULD treat this as a sev:low vulnerability in your application. The relevant attack is complex and usually requires some degree of privileged access to pull off.
        • The fix is to migrate to Version4.
        • If you're using Key-IDs, then you probably want to migrate just in case, but we're not aware of any actual risks when the attacker can only switch between a finite set of possible keys outside their control.
        • If you need an interim mitigation (because, for some reason, you can't just migrate), it's possible to by including a KDF output of your symmetric key. (See below.)
      • If you aren't, it's not really a big deal. Carry on.
    • @thaidn disclosed an unfortunate failure mode that's unlikely to ever happen: If the CSPRNG returns a predictable output (for example, all NUL bytes), then the derived nonce will be the hash of your plaintext payload. RNG failures with PHP 7's CSPRNG are fatal errors, so a silently-failing CSPRNG is very unlikely, but if it ever did happen, attackers could leak your plaintext by brute-forcing the hash that produces the nonce. This is only relevant to v1.local and v2.local.

      • If it ever did happen in general, it would break the security of key/nonce generation in all cryptographic applications.
    • How RSA signatures are used in PASETO v1.public tokens do not offer Exclusive Ownership. Learn more about why it matters.

      Bottom-line: digital signatures yield guarantees about a message for a given public key, not the other way round. -- Thomas Pornin

    These are all nuisances we sought to fix in Version 3 and Version 4. As a result, the new versions offer a more robust argument for their security in a wider range of real-world use cases.

    What would a Version2 mitigation look like?

    Use this to commit/verify that the same key was used for a given PASETO:

    <?php
    function v2key_commit(SymmetricKey $key): string {
        return sodium_bin2hex(
            sodium_crypto_generichash('MITIGATION_COMMIT_KEY', $key->raw())
        );
    }
    
    function v2key_verify(SymmetricKey $key, string $commitment): bool {
        $calc = v2key_commit($key);
        return hash_equals($calc, $commitment);
    }
    

    Just store the commitment hash inside the footer, then verify it before parsing. Since this will be bundled with the token (and cryptographically bound to it through the Poly1305 authentication tag), even if an attacker can perform some trickery, v2key_verify() will return false if the target is decrypting the token with the wrong key.

    Is there a CVE identifier for any of those issues?

    No, a CVE ID is not appropriate for non-vulnerabilities.

    If any system is specifically impacted by the Poly1305 issue in v2.local tokens, and sets up the condition that makes the complex attack possible, then a CVE would be appropriate for that specific application. This generally means "wrote our own key-wrapping scheme based on AES-GCM or ChaCha20-Poly1305".

    Although the RNG failure mode sounds scary, the security of your entire system depends on the CSPRNG not failing. This is sort of like getting a DoS attack to work from root. You will almost certainly never be impacted by this.

    If any system is affected by the lack of Exclusive Ownership in v1.public tokens, then a) we want to hear about this system and b) a CVE definitely would be appropriate for whatever was built--but EO was never a stated goal for v1.public tokens, so its absence doesn't qualify as a vulnerability in PASETO.

    We believe that requesting a CVE identifier out of an abundance of caution will only create alert fatigue for the overwhelming majority of systems that will not be at risk.

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Jan 20, 2021)

    The RFC work has been moved to paseto-standard/paseto-rfc

    Fixes:

    • #113, #124 - PHP 8 is now supported
    • #112 - The code now refers to libsodium constants, not sodium_compat (which are polyfilled anyway)
    • #120 - Return an object instead of an array if claims is empty
    • #118 - Fixed isValid()
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Oct 16, 2018)

  • v1.0.1(Apr 20, 2018)

  • v1.0.0(Apr 20, 2018)

    It turns out, we don't need permission from the IETF to use PASETO in the real world (i.e. OAuth2). This is fortunate, because it's unlikely for them to accept a JWT alternative in the first place, no matter how doomed their christened standard may be.

    Based on the feedback we've already received from security and cryptography experts around the world, this is simple and usable enough to use in the real world. So there's no point in delaying a stable release any further.

    The documentation and reference implementation has been updated with some feedback from the RFC review process (i.e. optional footer handling).

    Protocol changes:

    None. We're quite happy with the way Paseto is currently designed.

    PHP Library Changes:

    • If you pass a footer to the third argument, it will be evaluated with strict constant-time equality. Otherwise, it will strip it off the token and decoded from base64.

    Documentation Changes:

    • Handling optional footers is less strict, as per RFC draft feedback.
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Apr 19, 2018)

    We've completed draft-00 of our proposed RFC. This makes us one step closer to tagging v1.0.0.

    Protocol changes:

    None. We're quite happy with the way Paseto is currently designed.

    PHP Library Changes:

    • Use setSignatureMode() instead of setEncryptionMode() for Version1. The end result was the same, but it's important to be explicit about our intent in our implementation.
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Mar 19, 2018)

    Protocol changes:

    None. We're quite happy with the way Paseto is currently designed.

    PHP Library Changes:

    • A lot of mostly-internal type-safety work done by @aidantwoods
      • Fixed: A footer of 0 would not append to the token due to PHP's treatment of falsy values.
    • We explicitly tell phpseclib to use e = 65537 for version 1.

    Other Changes:

    • A lot of documentation has been fleshed out. Give it a read here: https://github.com/paragonie/paseto/tree/master/docs
    • Several people have begun developing PASETO implementations in other programming languages. See all of them here.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Mar 4, 2018)

    Special thanks to @aidantwoods for contributing a lot to this minor release.

    Protocol changes:

    None. We're quite happy with the way Paseto is currently designed.

    PHP Library Changes:

    • JsonToken building was split out into a separate Builder class, to make key management easier to reason about.
    • Instead of a string constant containing a header, the version object itself is expected in a few places.
    • Purpose is now passed as an object rather than a string.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jan 31, 2018)

    Biggest change: We've changed our name from PAST to Paseto. It should be easier to find in a Google search.

    Other fixes since v0.3.0:

    • The HKDF constants have been updated to reflect the name change, and our test vectors use a full ISO 8601 DateTime string (including timezone).
    • #26 was fixed with our reference implementation.

    This may be our last pre-1.0.0 release. The only thing left to do (barring the discovery of any cryptography flaws unique to Paseto) is documentation work, including drafting an RFC to submit to the IETF.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jan 7, 2018)

    A lot has changed since v0.2.0! PAST is now a lot faster, simpler, and has a greater degree of misuse resistance.

    • seal has been removed.
    • auth has been removed.
    • enc has been renamed to local.
    • sign has been renamed to public.
    • We now use unpadded base64url encoding.
    • For encryption, nonces are now derived from the plaintext in addition to the OS CSPRNG, using HMAC-SHA384 (version 1) or keyed BLAKE2b (version 2). This should mitigate the risk of nonce reuse on systems or programming languages with insecure RNGs.
    • More unit tests.
    • More documentation. It should now be straightforward to implement PAST in other languages.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jan 4, 2018)

    PAST now has a basic reference implementation and a first draft for the specification.

    Notable change to the cryptography since v0.1.0: We now feed data into MACs and signature algorithms in such a way to minimize the risk of canonicalization attacks. Although no practical exploits are known for HMAC-SHA384 or Poly1305, simply concatenating different values together as one giant string seems like a needlessly cavalier design decision. Our new serialization format should effectively mitigate any risks.

    We're going to take some time to accept feedback from the community, polish up the documentation, and request review from professional cryptographers.

    Unless a game-over protocol flaw is discovered, the current implementation should be assumed stable enough to serve as a reference point for developing implementations in other programming languages. However, don't deploy this in production until v1.0.0 has been tagged and released.

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jan 2, 2018)

    The cryptography proof-of-concept is implemented. The remainder of the work is:

    • Documentation
    • Specification
    • User Experience Design
    • API Design
    • Making Formerly-JOSE-Users Happy with their Use Cases
      • (Unless they needed algorithm agility, in which case... No.)
    Source code(tar.gz)
    Source code(zip)
Owner
Paragon Initiative Enterprises
Technology should support your ambitions, not hinder them. We are a team of technology consultants that specialize in application security.
Paragon Initiative Enterprises
Learn Cookies and Tokens Security in Practice.

The full article is posted on my blog. The video presentation is shared here. The presentation slides are shared here. The exploit codes are shared he

HolyBugx 38 Aug 28, 2022
Easily define tokens and options that can be replaced in strings.

Token Replace This simple package allows you to define tokens that can be replaced in strings. Instead of a simple str_replace, Token Replace lets you

Jamie Holly 2 Dec 21, 2022
Implements a Refresh Token system over Json Web Tokens in Symfony

JWTRefreshTokenBundle The purpose of this bundle is manage refresh tokens with JWT (Json Web Tokens) in an easy way. This bundles uses LexikJWTAuthent

Marcos Gómez Vilches 568 Dec 28, 2022
Magic admin PHP SDK makes it easy to leverage Decentralized ID tokens to protect routes and restricted resources for your application.

Magic Admin PHP SDK The Magic Admin PHP SDK provides convenient ways for developers to interact with Magic API endpoints and an array of utilities to

magiclabs 17 Jun 26, 2022
A framework agnostic authentication & authorization system.

Sentinel Sentinel is a PHP 7.3+ framework agnostic fully-featured authentication & authorization system. It also provides additional features such as

Cartalyst 1.4k Dec 30, 2022
Vendor-Agnostic Two-Factor Authentication

Multi-Factor Designed to be a vendor-agnostic implementation of various Two-Factor Authentication solutions. Developed by Paragon Initiative Enterpris

Paragon Initiative Enterprises 139 Dec 21, 2022
php database agnostic authentication library for php developers

Whoo Whoo is a database agnostic authentication library to manage authentication operation easily. Whoo provides you a layer to access and manage user

Yunus Emre Bulut 9 Jan 15, 2022
Security Defense for Firebase's PHP-JWT Library

PHP-JWT-Guard Protect your code from being impacted by issue 351 in firebase/php-jwt. Installation First, install this library with Composer: composer

Paragon Initiative Enterprises 8 Nov 27, 2022
User registration and login form with validations and escapes for total security made with PHP.

Login and Sign Up with PHP User registration and login form with validations and escapes for total security made with PHP. Validations Required fields

Alexander Pérez 2 Jan 26, 2022
This system will provide security and comfortable opportunities to protect your gaming account.

VK Security – Auth system VK Security provides the ability to use game authorization inside in conjunction with the official VKontakte groups. Conveni

Victor Kasko 4 Dec 21, 2022
Rinvex Authy is a simple wrapper for @Authy TOTP API, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest API for developers and a strong authentication platform for the enterprise.

Rinvex Authy Rinvex Authy is a simple wrapper for Authy TOTP API, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest AP

Rinvex 34 Feb 14, 2022
Simple PASETO Auth support for Laravel PHP Framework

Laravel PASETO Simple PASETO Auth for Laravel PHP Framework using paragonie/paseto under the hood. Installation Standard Composer package installation

Ricardo Čerljenko 9 Jan 11, 2022
Learn Cookies and Tokens Security in Practice.

The full article is posted on my blog. The video presentation is shared here. The presentation slides are shared here. The exploit codes are shared he

HolyBugx 38 Aug 28, 2022
Security CSRF (cross-site request forgery) component provides a class CsrfTokenManager for generating and validating CSRF tokens.

Security Component - CSRF The Security CSRF (cross-site request forgery) component provides a class CsrfTokenManager for generating and validating CSR

Symfony 1.5k Jan 3, 2023
Faker-driven, configuration-based, platform-agnostic, locale-compatible data faker tool

Masquerade Faker-driven, platform-agnostic, locale-compatible data faker tool Point Masquerade to a database, give it a rule-set defined in YAML and M

elgentos ecommerce solutions 219 Dec 13, 2022
A multitool library offering access to recommended security related libraries, standardised implementations of security defences, and secure implementations of commonly performed tasks.

SecurityMultiTool A multitool library offering access to recommended security related libraries, standardised implementations of security defences, an

Pádraic Brady 131 Oct 30, 2022
Exploiting and fixing security vulnerabilities of an old version of E-Class. Project implemented as part of the class YS13 Cyber-Security.

Open eClass 2.3 Development of XSS, CSRF, SQLi, RFI attacks/defences of an older,vulnerable version of eclass. Project implemented as part of the clas

Aristi_Papastavrou 11 Apr 23, 2022
phpcs-security-audit is a set of PHP_CodeSniffer rules that finds vulnerabilities and weaknesses related to security in PHP code

phpcs-security-audit v3 About phpcs-security-audit is a set of PHP_CodeSniffer rules that finds vulnerabilities and weaknesses related to security in

Floe design + technologies 655 Jan 3, 2023