separate KDF (not a proper KDF for now)
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
//! Password-to-key derivation.
|
||||
//!
|
||||
//! This currently uses SHA3-256 directly and truncates the result to 24 bytes
|
||||
//! because `KeccakAead` accepts keys up to 24 bytes.
|
||||
//!
|
||||
//! This is not a proper password-based KDF. There is currently no salt,
|
||||
//! work factor, memory hardness, or iteration count.
|
||||
|
||||
use crate::keccak::sha3_256;
|
||||
|
||||
/// Length of the key produced for `KeccakAead`.
|
||||
pub const DERIVED_KEY_LEN: usize = 24;
|
||||
|
||||
/// Derive a 24-byte encryption key from a password.
|
||||
///
|
||||
/// The password is encoded as UTF-8 and hashed using the project's
|
||||
/// SHA3-256 implementation. The first 24 bytes of the digest are used
|
||||
/// as the AEAD key.
|
||||
pub fn derive_file_key(password: &str) -> [u8; DERIVED_KEY_LEN] {
|
||||
let digest = sha3_256(password.as_bytes());
|
||||
|
||||
let mut key = [0u8; DERIVED_KEY_LEN];
|
||||
key.copy_from_slice(&digest[..DERIVED_KEY_LEN]);
|
||||
|
||||
key
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
mod kdf;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub use kdf::derive_file_key;
|
||||
@@ -0,0 +1,26 @@
|
||||
use super::*;
|
||||
use crate::kdf::kdf::DERIVED_KEY_LEN;
|
||||
|
||||
#[test]
|
||||
fn key_has_expected_length() {
|
||||
assert_eq!(DERIVED_KEY_LEN, 24);
|
||||
|
||||
let key = derive_file_key("test password");
|
||||
assert_eq!(key.len(), DERIVED_KEY_LEN);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn same_password_same_key() {
|
||||
let a = derive_file_key("correct horse battery staple");
|
||||
let b = derive_file_key("correct horse battery staple");
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_passwords_produce_different_keys() {
|
||||
let a = derive_file_key("password1");
|
||||
let b = derive_file_key("password2");
|
||||
|
||||
assert_ne!(a, b);
|
||||
}
|
||||
+16
-18
@@ -4,12 +4,14 @@ use std::path::PathBuf;
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
mod file_crypt;
|
||||
mod kdf;
|
||||
mod keccak;
|
||||
mod keccak_aead;
|
||||
|
||||
use file_crypt::{MAX_KEY_LEN, decrypt_file, encrypt_file};
|
||||
use file_crypt::{decrypt_file, encrypt_file};
|
||||
use kdf::derive_file_key;
|
||||
|
||||
/// File encryption utility using KeccakAead.
|
||||
/// Encrypt and decrypt files using KeccakAead.
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
name = "filecrypt-rs",
|
||||
@@ -54,18 +56,6 @@ enum Command {
|
||||
},
|
||||
}
|
||||
|
||||
/// Derive the fixed-length AEAD key from a password.
|
||||
///
|
||||
/// SHA-3-256 produces 32 bytes, while `KeccakAead` currently accepts keys from 16 through 24 bytes. Therefore we use the first 24 bytes.
|
||||
fn derive_key(password: &str) -> [u8; MAX_KEY_LEN] {
|
||||
let digest = keccak::sha3_256(password.as_bytes());
|
||||
|
||||
let mut key = [0u8; MAX_KEY_LEN];
|
||||
key.copy_from_slice(&digest[..MAX_KEY_LEN]);
|
||||
|
||||
key
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
@@ -75,11 +65,15 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
output,
|
||||
password,
|
||||
} => {
|
||||
let key = derive_key(&password);
|
||||
let key = derive_file_key(&password);
|
||||
|
||||
encrypt_file(&input, &output, &key)?;
|
||||
|
||||
println!("Encrypted '{}' -> '{}'", input.display(), output.display());
|
||||
println!(
|
||||
"Encrypted '{}' -> '{}'",
|
||||
input.display(),
|
||||
output.display()
|
||||
);
|
||||
}
|
||||
|
||||
Command::Decrypt {
|
||||
@@ -87,11 +81,15 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
output,
|
||||
password,
|
||||
} => {
|
||||
let key = derive_key(&password);
|
||||
let key = derive_file_key(&password);
|
||||
|
||||
decrypt_file(&input, &output, &key)?;
|
||||
|
||||
println!("Decrypted '{}' -> '{}'", input.display(), output.display());
|
||||
println!(
|
||||
"Decrypted '{}' -> '{}'",
|
||||
input.display(),
|
||||
output.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user