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:
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");
}