14 stable releases
2.0.1 | Oct 29, 2024 |
---|---|
2.0.0 | Oct 28, 2024 |
1.2.3 | Aug 4, 2024 |
1.2.2 | Mar 8, 2024 |
1.0.5 | Oct 17, 2023 |
#194 in Cryptography
66 downloads per month
73KB
1K
SLoC
Bitwark β
Provides robust security for Rust applications through compact binary tokens and automated cryptographic defenses.
π Introduction
Bitwark is your go-to library for enhancing security in Rust applications. It offers a streamlined, bandwidth-friendly version of JSON Web Tokens (JWTs) and includes features like automatic key rotation and data salting to bolster your app's defenses.
π Key Features:
- Compact Tokens: Uses binary format for signed payloads, saving space compared to traditional JWTs.
- Advanced Encryption: Employs EdDSA with Blake3 for robust signing and verification out of the box.
- Dynamic Key Rotation: Simplifies the process to update keys and salts, keeping your security measures up-to-date.
- Enhanced Security with Salting: Adds random data to payloads, making it tougher for attackers to crack.
- Performance Optimized: Designed to be lightweight, ensuring your applications run smoothly under pressure.
π οΈ Getting Started
Explore the secure features of Bitwark for your Rust applications:
All-in-One Example (Alternative to JWT)
Imagine you have a structure you wish to sign and send back to the user:
#[derive(Serialize, Deserialize, Clone)]
pub struct Token {
pub user_id: u32,
pub permissions: Vec<String>,
}
First, generate a key that expires after 10 minutes, though you can set it for days, months, or years as needed. For a non-expiring key, simply use EdDsaKey::generate()
:
let exp_key = AutoExpiring::<EdDsaKey>::generate(
Duration::minutes(10)
).unwrap();
Next, create the token. SaltyExpiringSigned
adds a default 64-byte salt and includes an expiration time:
let token_object = Token { user_id: 123, permissions: vec!["Read".to_string(), "Write".to_string()] };
let token = SaltyExpiringSigned::<Token>::new(
chrono::Duration::minutes(10),
token_object
).unwrap();
Finally, prepare the token for the client. You can return it as bytes or convert it to base64:
let token_bytes: Vec<u8> = token.encode_and_sign(&*exp_key).unwrap();
When the user provides this token to your service, verifying it is straightforward:
let token = SaltyExpiringSigned::<Token>::decode_and_verify(&token_bytes, &*exp_key).unwrap();
if token.permissions.contains(&String::from("Read")) {
// Proceed with the user's request
}
More Comprehensive Examples Follow
Signed Payload decoded as binary (alternative to JWT)
use bitwark::{
exp::AutoExpiring,
signed_exp::ExpiringSigned,
salt::Salt64,
keys::{ed::EdDsaKey},
};
use serde::{Serialize, Deserialize};
use chrono::Duration;
#[derive(Serialize, Deserialize)]
pub struct Claims {
pub permissions: Vec<String>,
}
// Generate an EdDSA key pair and salt with a validity period
let exp_key = AutoExpiring::<EdDsaKey>::generate(
Duration::minutes(10)
).unwrap();
let exp_salt = AutoExpiring::<Salt64>::generate(
Duration::minutes(5)
).unwrap();
// Instantiate a token with specified claims.
let claims = Claims {
permissions: vec![
"users:read".to_string(),
"users:write".to_string()
],
};
let token = ExpiringSigned::<Claims>::new(
Duration::seconds(120), claims
).unwrap();
// Create a binary encoding of the token, signed with key and salt.
let signed_token_bytes = token.encode_and_sign_salted(
&exp_salt, &*exp_key
).expect("Failed to sign token");
// Decode the token and verify its signature and validity.
let decoded_token = ExpiringSigned::<Claims>::decode_and_verify_salted(
&signed_token_bytes, &exp_salt, &*exp_key
).expect("Failed to decode a token");
assert_eq!(
2,
decoded_token.permissions.len(),
"Failed to find 2 permissions"
);
Key Rotation
use bitwark::{payload::SignedPayload, keys::ed::EdDsaKey, keys::CryptoKey, Generator};
use chrono::Duration;
// creating a key
let key = EdDsaKey::generate()?;
// Rotating key
let mut expiring_key = Expiring<EdDsaKey>::new(Duration::seconds(10), key);
if expiring_key.has_expired() {
expiring_key.roll()?;
}
// Creating a payload
let payload = SignedPayload::<String>::new("A signed message".to_string());
// Encode the payload with signature based on the expiring key
let signed_payload_bytes = payload.encode_and_sign(&expiring_key)?;
// Decode the signed payload with verifying signature with payload's integrity
let decoded_payload = SignedPayload::<String>::decode_and_verify(&signed_payload_bytes, &expiring_key)?;
assert_eq!(*decoded_payload, *payload);
Salt Example
use bitwark::{
salt::Salt64,
exp::AutoExpiring,
key::ed::EdDsaKey,
Rotation, Generator
};
use bitwark::payload::SignedPayload;
use chrono::Duration;
// Make a new salt.
let salt = Salt64::generate().unwrap();
// Make a salt that lasts for 10 seconds.
let mut expiring_salt = AutoExpiring::<Salt64>::new(
Duration::seconds(10), salt
).unwrap();
// Change the salt if it's too old.
if expiring_salt.has_expired() {
expiring_salt
.rotate()
.expect("Salt rotation failed.");
}
// Make a key that lasts for 120 seconds.
let key = AutoExpiring::<EdDsaKey>::generate(
Duration::seconds(120)
).unwrap();
// Make a payload for signing
let payload = SignedPayload::<String>::new(
"Hello, world!".to_string()
);
// Combine message and signature into one piece.
let signature_bytes = payload.encode_and_sign_salted(
&expiring_salt, &*key
).expect("Failed to encode");
// Separate message and signature, verifying validity.
let decoded_result =
SignedPayload::<String>::decode_and_verify_salted(
&signature_bytes, &expiring_salt, &*key
);
assert!(decoded_result.is_ok());
π‘ Motivation
In today's digital landscape, security must not come at the expense of performance. Bitwark addresses this challenge by:
- Providing lightweight, bandwidth-efficient tokens for data exchange.
- Offering robust security features like automatic key rotation and salting to adapt to evolving threats.
π± Contribution
Be a Part of Bitwarkβs Journey!
We believe in the power of community, and Bitwark thrives on contributions from developers like you:
- Propose Ideas: Found a bug or have an idea? Open an Issue!
- Code Contributions: Enhance Bitwark by submitting Pull Requests with your code.
- Documentation: Help us keep our documentation clear and helpful.
- Engage: Participate in community discussions to shape Bitwark's future.
π License
Bitwark is licensed under the MIT License or Apache-2.0 to ensure it remains accessible for all developers.
Dependencies
~11β20MB
~390K SLoC