feat: pbe encryption

This commit is contained in:
2025-05-05 23:35:41 +08:00
parent c0ea3b773d
commit 57c3ec57df
4 changed files with 16 additions and 8 deletions

2
Cargo.lock generated
View File

@@ -508,7 +508,7 @@ dependencies = [
[[package]] [[package]]
name = "card-cli" name = "card-cli"
version = "1.12.7" version = "1.12.8"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"authenticator 0.3.1", "authenticator 0.3.1",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "card-cli" name = "card-cli"
version = "1.12.7" version = "1.12.8"
authors = ["Hatter Jiang <jht5945@gmail.com>"] authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018" edition = "2018"

View File

@@ -22,6 +22,7 @@ impl Command for CommandImpl {
.help("Plaintext"), .help("Plaintext"),
) )
.arg(Arg::with_name("with-pbe").long("with-pbe").help("With PBE encryption")) .arg(Arg::with_name("with-pbe").long("with-pbe").help("With PBE encryption"))
.arg(Arg::with_name("double-pin-check").long("double-pin-check").help("Double PIN check"))
.arg(Arg::with_name("pbe-iteration").long("pbe-iteration").takes_value(true).help("PBE iteration, default 100000")) .arg(Arg::with_name("pbe-iteration").long("pbe-iteration").takes_value(true).help("PBE iteration, default 100000"))
.arg(cmdutil::build_json_arg()) .arg(cmdutil::build_json_arg())
} }
@@ -32,9 +33,10 @@ impl Command for CommandImpl {
let mut text = sub_arg_matches.value_of("plaintext").unwrap().to_string(); let mut text = sub_arg_matches.value_of("plaintext").unwrap().to_string();
let with_pbe = sub_arg_matches.is_present("with-pbe"); let with_pbe = sub_arg_matches.is_present("with-pbe");
if with_pbe { if with_pbe {
let double_pin_check = sub_arg_matches.is_present("double-pin-check");
let iteration = sub_arg_matches.value_of("pbe-iteration") let iteration = sub_arg_matches.value_of("pbe-iteration")
.map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000); .map(|x| x.parse::<u32>().unwrap()).unwrap_or(100000);
text = pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, &text)?; text = pbeutil::simple_pbe_encrypt_with_prompt_from_string(iteration, &text, double_pin_check)?;
} }
let hmac_encrypt_ciphertext = hmacutil::hmac_encrypt_from_string(&text)?; let hmac_encrypt_ciphertext = hmacutil::hmac_encrypt_from_string(&text)?;

View File

@@ -7,8 +7,8 @@ use rust_util::XResult;
const PBE_ENC_PREFIX: &str = "pbe_enc:"; const PBE_ENC_PREFIX: &str = "pbe_enc:";
pub fn simple_pbe_encrypt_with_prompt_from_string(iteration: u32, plaintext: &str) -> XResult<String> { pub fn simple_pbe_encrypt_with_prompt_from_string(iteration: u32, plaintext: &str, password_double_check: bool) -> XResult<String> {
simple_pbe_encrypt_with_prompt(iteration, plaintext.as_bytes()) simple_pbe_encrypt_with_prompt(iteration, plaintext.as_bytes(), password_double_check)
} }
pub fn simple_pbe_decrypt_with_prompt_to_string(ciphertext: &str) -> XResult<String> { pub fn simple_pbe_decrypt_with_prompt_to_string(ciphertext: &str) -> XResult<String> {
@@ -16,9 +16,15 @@ pub fn simple_pbe_decrypt_with_prompt_to_string(ciphertext: &str) -> XResult<Str
Ok(String::from_utf8(plaintext)?) Ok(String::from_utf8(plaintext)?)
} }
pub fn simple_pbe_encrypt_with_prompt(iteration: u32, plaintext: &[u8]) -> XResult<String> { pub fn simple_pbe_encrypt_with_prompt(iteration: u32, plaintext: &[u8], password_double_check: bool) -> XResult<String> {
let pin = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required"); let pin1 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
simple_pbe_encrypt(&pin, iteration, plaintext) if password_double_check {
let pin2 = opt_value_result!(pinutil::get_pin(None), "Simple PBE password required");
if pin1 != pin2 {
return simple_error!("Two PINs mismatch");
}
}
simple_pbe_encrypt(&pin1, iteration, plaintext)
} }
pub fn simple_pbe_decrypt_with_prompt(ciphertext: &str) -> XResult<Vec<u8>> { pub fn simple_pbe_decrypt_with_prompt(ciphertext: &str) -> XResult<Vec<u8>> {