Crate rusty_paserk

Crate rusty_paserk 

Source
Expand description

Platform-Agnostic Serialized Keys

PASERK is an extension to PASETO that provides key-wrapping and serialization.

§Motivation

PASETO provides two types of tokens (called a purpose) in each of its versions:

PurposeCryptographic Operation
localSymmetric-key authenticated encryption with additional data (AEAD)
publicAsymmetric-key digital signatures (no encryption)

These two token modes solve at least 80% of use cases for secure tokens. You can even solve unencrypted symmetric-key authentication by storing your claims in the unencrypted footer, rather than encrypting them.

The use-cases that PASETO doesn’t address out of the box are:

  • Key-wrapping
  • Asymmetric encryption
  • Password-based key encryption

PASERK aims to provide an answer for these circumstances, as well as provide a consistent standard for the encoding of PASETO keys.

§PASERK

A serialized key in PASERK has the format:

k[version].[type].[data]

Where [version] is an integer, [data] is the (typically base64url-encoded) payload data, and [type] is one of the items in the following table:

PASERK TypeMeaningPASETO Compatibility[data] Encoded?Safe in Footer?
lidUnique Identifier for a separate PASERK for local PASETOs.localYesYes
pidUnique Identifier for a separate PASERK for public PASETOs. (Public Key)publicYesYes
sidUnique Identifier for a separate PASERK for public PASETOs. (Secret Key)publicYesYes
localSymmetric key for local tokens.localYesNo
publicPublic key for verifying public tokens.publicYesNo
secretSecret key for signing public tokens.publicYesNo
sealSymmetric key wrapped using asymmetric encryption.localYesYes
local-wrapSymmetric key wrapped by another symmetric key.localNoYes
local-pwSymmetric key wrapped using password-based encryption.localYesNo
secret-wrapAsymmetric secret key wrapped by another symmetric key.publicNoYes
secret-pwAsymmetric secret key wrapped using password-based encryption.publicYesNo

§implementation

This library offers each of the key types and PASERK types from PASETO V3/4 as a unique rust type.

§Keys

Since PASETO identifies 3 different key types, so do we. They are as follows

  • Local - For local symmetric encryption.
  • Public - For public asymmetric verification and encryption
  • Secret - For public asymmetric signing and decryption

Keys are also versioned. We support the following versions

  • [V3] - NIST based modern cryptography (hmac, sha2, aes, p384)
  • V4 - Sodium based modern cryptography (blake2b, chacha, ed25519)

§IDs: lid/pid/sid

The KeyId type represents key ids. Building a KeyID is as simple as

use rusty_paserk::{Key, Local, KeyId, V4};

let local_key = Key::<V4, Local>::new_os_random();
let kid: KeyId<V4, Local> = local_key.into();
// kid.to_string() => "k4.lid.XxPub51WIAEmbVTmrs-lFoFodxTSKk8RuYEJk3gl-DYB"

You can also parse the KeyId from a string to have a smaller in memory representation. It can be safely shared and stored.

§Plaintext: local/public/secret

The PlaintextKey type represents the base64 encoded plaintext key types.

use rusty_paserk::{Key, Local, PlaintextKey, V4};

let local_key = Key::<V4, Local>::new_os_random();
let key = PlaintextKey(local_key);
// key.to_string() => "k4.local.bkwMkk5uhGbHAISf4bzY5nlm6y_sfzOIAZTfj6Tc9y0"

These are considered sensitive and should not be shared (besides public keys)

§Seal

Using a public key, you can seal a local key. Using the corresponding private key, you can unseal the key again.

use rusty_paserk::{SealedKey, Key, Local, Secret, V4};

let key = Key::<V4, Local>::new_os_random();

let secret_key = Key::<V4, Secret>::new_os_random();
let public_key = secret_key.public_key();

let sealed = key.seal(&public_key).to_string();
// => "k4.seal.23KlrMHZLW4muL75Rnuqtaro9F16mqDNvmCbgDXi2IdNyWmjrbTVBEih1DhSI_5xp7b7mCHSFo1DMv-9GtZUSpyi4646XBxpbFShHjJihF_Af8maWsDqdzOof76ia0Cv"

let sealed: SealedKey<V4> = sealed.parse().unwrap();
let key2 = sealed.unseal(&secret_key).unwrap();
assert_eq!(key, key2);

See the SealedKey type for more info.

§Wrap local-wrap/secret-wrap

Using a local key, you can wrap a local or a secret key. It can be unwrapped using the same local key.

use rusty_paserk::{PieWrappedKey, Key, Local, V4};

let wrapping_key = Key::<V4, Local>::new_os_random();

let local_key = Key::<V4, Local>::new_os_random();

let wrapped_local = local_key.wrap_pie(&wrapping_key).to_string();
// => "k4.local-wrap.pie.RcAvOxHI0H-0uMsIl6KGcplH_tDlOhW1omFwXltZCiynHeRNH0hmn28AkN516h3WHuAReH3CvQ2SZ6mevnTquPETSd3XnlcbRWACT5GLWcus3BsD4IFWm9wFZgNF7C_E"

let wrapped_local: PieWrappedKey<V4, Local> = wrapped_local.parse().unwrap();
let local_key2 = wrapped_local.unwrap_key(&wrapping_key).unwrap();
assert_eq!(local_key, local_key2);

See the PieWrappedKey type for more info.

§Password wrapping local-pw/secret-pw

Using a password, you can wrap a local or a secret key. It can be unwrapped using the same password.

use rusty_paserk::{PwWrappedKey, Key, Local, Secret, V4, Argon2State};

let password = "hunter2";

let secret_key = Key::<V4, Secret>::new_os_random();

let wrapped_secret = secret_key.pw_wrap(password.as_bytes()).to_string();
// => "k4.secret-pw.uscmLPzUoxxRfuzmY0DWcAAAAAAEAAAAAAAAAgAAAAHVNddVDnjRCc-ZmT-R-Xp7c7s4Wn1iH0dllAPFBmknEJpKGYP_aPoxVzNS_O93M0sCb68t7HjdD-jXWp-ioWe56iLoA6MlxE-SmnKear60aDwqk5fYv_EMD4Y2pV049BvDNGNN-MzR6fwW_OlyhV9omEvxmczAujM"

let wrapped_secret: PwWrappedKey<V4, Secret> = wrapped_secret.parse().unwrap();
let secret_key2 = wrapped_secret.unwrap_key(password.as_bytes()).unwrap();
assert_eq!(secret_key, secret_key2);

See the PwWrappedKey type for more info.

Modules§

internal
Internally used traits for encryption version configuration

Structs§

Argon2Statev4
Argon2 parameters for V4 password wrapping
Key
A PASETO key.
KeyId
Unique ID for a key
Local
Local symmetric encryption/decrypting keys
PieWrappedKey
Paragon Initiative Enterprises standard key-wrapping
PlaintextKey
A key encoded in base64. It is not a secure serialization.
Public
Public verifying/encrypting keys
PwWrappedKey
Password wrapped keys
SealedKey
A local key encrypted with an asymmetric wrapping key.
Secret
Secret signing/decrypting keys
V4v4
Version 4: Sodium Modern

Enums§

PasetoError
Potential errors from attempting to build a token claim

Traits§

KeyType
General information about key types
SafeForFooter
Whether the key serialization is safe to be added to a PASETO footer.
Version
General information about a PASETO/PASERK version