cinderella

[unmaintained] simple CI engine
Log | Files | Refs | README | LICENSE

commit ea1a522320d48eea79634167a67d962a5fa53659
parent 3d1486f6757335e2710ac5c7133cb27addc7b090
Author: Stefan Koch <programming@stefan-koch.name>
Date:   Sat, 23 Nov 2019 23:34:54 +0100

generate a key for a string password

Diffstat:
Msrc/crypto.rs | 36+++++++++++++++++++++++++++++++-----
Msrc/lib.rs | 2+-
2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/crypto.rs b/src/crypto.rs @@ -3,22 +3,48 @@ use std::fs::File; use serde::{Serialize, Deserialize}; use rmp_serde; -use sodiumoxide::crypto::secretbox; -use sodiumoxide::crypto::secretbox::xsalsa20poly1305::Nonce; +use sodiumoxide::crypto::secretbox::{self, Key, Nonce}; +use sodiumoxide::crypto::pwhash::{self, Salt}; #[derive(Serialize, Deserialize)] pub struct CryptoFile { + pwsalt: Salt, nonce: Nonce, content: Vec<u8>, } -pub fn encrypt_string(plaintext: &str) -> Vec<u8> { - let key = secretbox::gen_key(); +pub struct SaltedKey { + pwsalt: Salt, + key: Key, +} + +pub fn gen_key_from_pw(password: &str) -> SaltedKey { + let salt = pwhash::gen_salt(); + + // cf. https://docs.rs/sodiumoxide/0.2.5/sodiumoxide/crypto/pwhash/index.html#example-key-derivation + let mut k = secretbox::Key([0; secretbox::KEYBYTES]); + { + let secretbox::Key(ref mut kb) = k; + pwhash::derive_key(kb, password.as_bytes(), &salt, + pwhash::OPSLIMIT_INTERACTIVE, + pwhash::MEMLIMIT_INTERACTIVE).unwrap(); + + SaltedKey { + key: Key::from_slice(kb).unwrap(), + pwsalt: salt + } + } +} + +pub fn encrypt_string(plaintext: &str, password: &str) -> Vec<u8> { + let salted_key = gen_key_from_pw(password); let nonce = secretbox::gen_nonce(); - let ciphertext = secretbox::seal(plaintext.as_bytes(), &nonce, &key); + let ciphertext = secretbox::seal(plaintext.as_bytes(), + &nonce, &salted_key.key); let f = CryptoFile { nonce, + pwsalt: salted_key.pwsalt, content: ciphertext, }; diff --git a/src/lib.rs b/src/lib.rs @@ -130,7 +130,7 @@ pub fn run(exec_config: &ExecutionConfig) { pub fn encrypt(filepath: String) { let plaintext = "some data"; - let cipher = crypto::encrypt_string(plaintext); + let cipher = crypto::encrypt_string(plaintext, "my-password"); fs::write(filepath, cipher).expect("Unable to write file"); }