PHP Classes

File: docs/01-Protocol-Versions/Version2.md

Recommend this page to a friend!
  Classes of Scott Arciszewski   PHP PASeTo   docs/01-Protocol-Versions/Version2.md   Download  
File: docs/01-Protocol-Versions/Version2.md
Role: Auxiliary data
Content type: text/markdown
Description: Auxiliary data
Class: PHP PASeTo
Encrypt and decrypt data with PaSeTO protocol
Author: By
Last change:
Date: 4 years ago
Size: 4,071 bytes
 

Contents

Class file image Download

Paseto Version 2

Encrypt

Given a message m, key k, and optional footer f.

  1. Set header `h` to `v2.local.`
  2. Generate 24 random bytes from the OS's CSPRNG.
  3. Calculate BLAKE2b of the message `m` with the output of step 2 as the key, with an output length of 24. This will be our nonce, `n`. * This step is to ensure that an RNG failure does not result in a nonce-misuse condition that breaks the security of our stream cipher.
  4. Pack `h`, `n`, and `f` together (in that order) using PAE. We'll call this `preAuth`.
  5. Encrypt the message using XChaCha20-Poly1305, using an AEAD interface such as
    the one provided in libsodium.
    c = crypto_aead_xchacha20poly1305_encrypt(
        message = m
        aad = preAuth
        nonce = n
        key = k
    );
    
  6. If `f` is: * Empty: return h || b64(n || c) * Non-empty: return h || b64(n || c) || `.` || base64url(f) * ...where || means "concatenate"

Decrypt

Given a message m, key k, and optional footer f.

  1. If `f` is not empty, implementations MAY verify that the value appended to the token matches some expected string `f`, provided they do so using a constant-time string compare function.
  2. Verify that the message begins with `v2.local.`, otherwise throw an exception. This constant will be referred to as `h`.
  3. Decode the payload (`m` sans `h`, `f`, and the optional trailing period between `m` and `f`) from base64url to raw binary. Set: * `n` to the leftmost 24 bytes * `c` to the middle remainder of the payload, excluding `n`.
  4. Pack `h`, `n`, and `f` together (in that order) using PAE. We'll call this `preAuth`
  5. Decrypt `c` using `XChaCha20-Poly1305`, store the result in `p`.
    p = crypto_aead_xchacha20poly1305_decrypt(
       ciphertext = c
       aad = preAuth
       nonce = n
       key = k
    );
    
  6. If decryption failed, throw an exception. Otherwise, return `p`.

Sign

Given a message m, Ed25519 secret key sk, and optional footer f (which defaults to empty string):

  1. Set `h` to `v2.public.`
  2. Pack `h`, `m`, and `f` together using PAE (pre-authentication encoding). We'll call this `m2`.
  3. Sign `m2` using Ed25519 `sk`. We'll call this `sig`.
    sig = crypto_sign_detached(
        message = m2,
        private_key = sk
    );
    
  4. If `f` is: * Empty: return "`h` || base64url(`m` || `sig`)" * Non-empty: return "`h` || base64url(`m` || `sig`) || `.` || base64url(`f`)" * ...where || means "concatenate" * Note: `base64url()` means Base64url from RFC 4648 without `=` padding.

Verify

Given a signed message sm, public key pk, and optional footer f (which defaults to empty string):

  1. If `f` is not empty, implementations MAY verify that the value appended to the token matches some expected string `f`, provided they do so using a constant-time string compare function.
  2. Verify that the message begins with `v2.public.`, otherwise throw an exception. This constant will be referred to as `h`.
  3. Decode the payload (`sm` sans `h`, `f`, and the optional trailing period between `m` and `f`) from base64url to raw binary. Set: * `s` to the rightmost 64 bytes * `m` to the leftmost remainder of the payload, excluding `s`
  4. Pack `h`, `m`, and `f` together using PAE. We'll call this `m2`.
  5. Use Ed25519 to verify that the signature is valid for the message:
    valid = crypto_sign_verify_detached(
        signature = s,
        message = m2,
        public_key = pk
    );
    
  6. If the signature is valid, return `m`. Otherwise, throw an exception.