1 stable release
1.0.0 | Feb 18, 2021 |
---|
#9 in #session-keys
45KB
869 lines
LiteSession
Create Session Tokens that are Resilient to Misuse and Highjacking
lib.rs
:
LiteSession is a token generator for secure tokens that can be used in HTTP auth headers, cookies, in place of Json Web Tokens, in IoT and anywhere else where secure tokens are needed for communication between clients and servers. It provides Keyed-Hash Message authentication codes with associated client data in either encrypted (default settings) or unencrypted form.
The general form of the algorithm is
identifier | issued | expiry | (data)k | nonce | ConfidentialityMode | Blake3HMAC( username | issued | expiration | data | session key, k)
where `k = Blake3HMAC(user | issued | expiry | ConfidentialityMode, sk)`
The steps involved include:
-
Generate a
random identifier
-
Generate an
issued time
andexpiry time
in nanoseconds accuracy -
generate the
encryption key
to encrypt the data portion of the token. using algorithmk = Blake3HMAC(identifier | issued | expiry | ConfidentialityMode, sk)
- Create an empty string
encryption_key
- Append
identifier
toencryption_key
- Append
issued
toencryption_key
- Append
expiry
toencryption_key
- Append
ConfidentialityMode
toencryption_key
- Perform a HMAC function to the
encryption_key
using Blake3 in keyed mode and theserver_key
as the key - Return the result of the Blake3 operation above in
hex
or as astring
- Create an empty string
-
Encrypt the data using
ChaCha8
encryption using the Blake3Hash above as the encryption key -
Return the encrypted data and
nonce
-
Perform a Blake3Hmac on
identifier | issued | expiry | (data)k | nonce | ConfidentialityMode
-
Generate the token:
- Create an empty string called
token
- Append
identifier
totoken
- Append
issued
totoken
- Append
expiry
totoken
- Append
encrypted data
totoken
- Append
nonce
totoken
- Append
ConfidentialityMode
totoken
- Append
Blake3Hmac
totoken
- Return the token as a string or hex
The token generated is in the format
identifier⊕issued⊕expiry⊕ciphertext⊕nonce⊕confidentiality⊕hmac
- Create an empty string called
Verifying the token takes the following steps
- Check if the token structure is valid
- Destructure the token into its component fields
- Compare the
expiry
to the server'scurrent time
and returnSessionExpired
as theTokenOutcome
- Compute the encryption key as follows:
k=HMAC(identifier | issued | expiry | ConfidentialityMode, sk)
- Decrypt the encrypted data using
k
. - Compute
Blake3HMAC(identifier |issued | expiry | ciphertext | nonce | ConfidentialityMode | session key, k),
- Return
TokenOutcome::TokenAuthetic
if the token matches orTokenOutcome::TokenRejected
if the token does not match
The Blake3
algorithm is used in keyed
mode where the key is a 32byte/256bit
in length
The ChaCha8
algorithm takes a 32byte/256bit
key and 12byte/96bit nonce
International Atomic Time(TAI)
is used for nanosecond accuracy and not having to deal with leap seconds and timezones
Using the session key
prevents volume
and Denning-Sacco
attacks
Usage
Creating a token
use lite_session::{LiteSessionToken, LiteSessionError, ConfidentialityMode, LiteSessionData, Role, LiteSessionMode};
use core::time::Duration;
fn main() -> Result<(), LiteSessionError> {
let mut token = LiteSessionToken::default();
let expiry = 60*60_u64;
token.expiry(expiry);
let mut data = LiteSessionData::default();
data.username("foo_user");
data.role(Role::SuperUser);
data.tag("Foo-Tag");
data.add_acl("Network-TCP");
data.add_acl("Network-UDP");
token.hmac_data(data);
token.confidential(true);
token.mode(LiteSessionMode::SessionID("foobarbaz".into()));
let server_key = [0_u8; 32];
let session_token = token.build_secure(&server_key)?;
Ok(())
}
Verifying a token
use lite_session::{LiteSessionToken, LiteSessionError, ConfidentialityMode, LiteSessionData, LiteSessionMode};
fn main() -> Result<(), LiteSessionError> {
let server_key = [0_u8; 32];
let mut destructured = LiteSessionToken::default();
let session_token = "5tl726krvgmhoe1pyc4jadqs3fw09bi8⊕40000000602e51ab3a8e2d17⊕40000000603013ab3a8e2d17⊕3cf157bed212d5b34122a713ea860ec373800e5004bff1a195d603305bd5b7921d1017e70ef599bc1f7ed949bd3c66c696d74a16487f95a3f6fd⊕jrzapflsi618⊕ConfidentialityMode::High⊕4faab373d7247dfb2d50e213e5cb66e415afc22066f71c2b966fdeabb11cac64";
let outcome = destructured.from_string(&server_key, &session_token)?;
Ok(())
}
Dependencies
~2.5MB
~59K SLoC