A library to work with Javascript Object Signing and Encryption (JOSE), including: * JSON Web Tokens (JWT) * JSON Web Signature (JWS) * JSON Web Encryption (JWE) * JSON Web Algorithms (JWA) * JSON Web Keys (JWK)
This was inspired by lawliet89/biscuit
,
which is itself based off Keats/rust-jwt
.
All cryptographic algorithms are chosen at compile time. This reduces any risk of the infamous 'none' attack.
The crate, does not support all, and probably will never support all of the features described in the various RFCs, including some algorithms and verification.
```rust use no_way::{JWT, jwa, jws, jwk, ClaimsSet, RegisteredClaims}; use serde::{Serialize, Deserialize};
// Define our own private claims
struct PrivateClaims { company: String, department: String, }
let signingkey = jwk::OctetKey::new("secret".tostring().into_bytes());
let expected_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\ eyJpc3MiOiJodHRwczovL3d3dy5hY21lLmNvbS8iLCJzdWIiOiJKb2huIERvZSIsImF1ZCI6Imh0dHBzOi8vYWNtZ\ S1jdXN0b21lci5jb20vIiwibmJmIjoxMjM0LCJjb21wYW55IjoiQUNNRSIsImRlcGFydG1lbnQiOiJUb2lsZXQgQ2\ xlYW5pbmcifQ.VFCl2un1Kc17odzOe2Ehf4DVrWddu3U4Ux3GFpOZHtc";
let expectedclaims = ClaimsSet::
let jwt = JWT::new(expected_claims.clone());
let token = jwt.encode::token
to your clients
// ... some time later, we get token back!
let encodedtoken: jws::Encoded
```rust use noway::{ClaimsSet, RegisteredClaims, JWT, JWE}; use noway::jwk; use noway::jwe::Encrypted; use noway::jwa::{kma, cea, sign}; use serde::{Serialize, Deserialize};
// Define our own private claims
struct PrivateClaims { company: String, department: String, }
// Craft our JWS
let expectedclaims = ClaimsSet::
let expectedjwt = JWT::new(expectedclaims.clone());
let signingkey = jwk::OctetKey::new("secret".tostring().intobytes());
let jws = expectedjwt.encode::
// Encrypt the token
// You would usually have your own AES key for this, but we will use a zeroed key as an example let key = jwk::OctetKey::new(vec![0; 256 / 8]);
/// We need to create a nonce for AES GCM encryption.
/// You must take care NOT to reuse the nonce.
/// You can simply treat the nonce as a 96 bit
/// counter that is incremented after every use
///
/// In this case, we're using a 64bit counter + a 32bit random prefix tag
fn generate_nonce() -> Vec
// fetch and increment the nonce counter
let nonce = NONCE.fetch_add(1, Ordering::Release);
// collect the bytes together and return them
let mut output = vec![0; 96/8];
output[0..32/8].copy_from_slice(&TAG.to_be_bytes());
output[32/8..].copy_from_slice(&nonce.to_be_bytes());
output
} let nonce = generate_nonce();
// Construct the JWE let jwe = JWE::new(jws.clone());
// Encrypt let encrypted_jwe = jwe.encrypt::< cea::A256GCM, // encrypt the contents with AES256 GCM kma::A256GCMKW, // perform key wrapping with AES256 GCM
(&key, nonce).unwrap();
let token = encryptedjwe.tostring();
// Now, send token
to your clients
// ... some time later, we get token back!
let token: Encrypted
// Decrypt let decrypted_jwe = token.decrypt::<_, cea::A256GCM>(&key).unwrap();
asserteq!(jws, decryptedjwe.payload); ```