feat: v0.4.3, add --digest-file for decrypt

This commit is contained in:
2023-10-17 22:27:25 +08:00
parent ddd3ac3b2d
commit 186330fe2c
5 changed files with 214 additions and 21 deletions

128
Cargo.lock generated
View File

@@ -117,7 +117,7 @@ dependencies = [
"num-traits", "num-traits",
"rusticata-macros", "rusticata-macros",
"thiserror", "thiserror",
"time", "time 0.3.30",
] ]
[[package]] [[package]]
@@ -384,7 +384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124"
dependencies = [ dependencies = [
"generic-array", "generic-array",
"rand_core", "rand_core 0.6.4",
"subtle", "subtle",
"zeroize", "zeroize",
] ]
@@ -561,7 +561,7 @@ dependencies = [
"hkdf", "hkdf",
"pem-rfc7468", "pem-rfc7468",
"pkcs8", "pkcs8",
"rand_core", "rand_core 0.6.4",
"sec1", "sec1",
"subtle", "subtle",
"zeroize", "zeroize",
@@ -589,7 +589,7 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [ dependencies = [
"rand_core", "rand_core 0.6.4",
"subtle", "subtle",
] ]
@@ -632,6 +632,18 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.7"
@@ -651,7 +663,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
] ]
[[package]] [[package]]
@@ -677,7 +689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
dependencies = [ dependencies = [
"ff", "ff",
"rand_core", "rand_core 0.6.4",
"subtle", "subtle",
] ]
@@ -888,7 +900,7 @@ dependencies = [
"num-integer", "num-integer",
"num-iter", "num-iter",
"num-traits", "num-traits",
"rand", "rand 0.8.5",
"serde", "serde",
"smallvec", "smallvec",
"zeroize", "zeroize",
@@ -1186,6 +1198,29 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
dependencies = [
"libc",
"rand 0.4.6",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@@ -1194,7 +1229,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha", "rand_chacha",
"rand_core", "rand_core 0.6.4",
] ]
[[package]] [[package]]
@@ -1204,9 +1239,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.6.4",
] ]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.4" version = "0.6.4"
@@ -1216,6 +1266,15 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.16"
@@ -1272,7 +1331,7 @@ dependencies = [
"num-traits", "num-traits",
"pkcs1", "pkcs1",
"pkcs8", "pkcs8",
"rand_core", "rand_core 0.6.4",
"sha2", "sha2",
"signature", "signature",
"spki", "spki",
@@ -1290,6 +1349,19 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "rust-crypto"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
dependencies = [
"gcc",
"libc",
"rand 0.3.23",
"rustc-serialize",
"time 0.1.45",
]
[[package]] [[package]]
name = "rust_util" name = "rust_util"
version = "0.6.43" version = "0.6.43"
@@ -1308,6 +1380,12 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"
@@ -1453,7 +1531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500"
dependencies = [ dependencies = [
"digest", "digest",
"rand_core", "rand_core 0.6.4",
] ]
[[package]] [[package]]
@@ -1599,6 +1677,17 @@ dependencies = [
"syn 2.0.38", "syn 2.0.38",
] ]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.30" version = "0.3.30"
@@ -1630,7 +1719,7 @@ dependencies = [
[[package]] [[package]]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "0.4.2" version = "0.4.3"
dependencies = [ dependencies = [
"aes-gcm-stream", "aes-gcm-stream",
"base64", "base64",
@@ -1644,9 +1733,10 @@ dependencies = [
"openpgp-card-pcsc", "openpgp-card-pcsc",
"p256", "p256",
"p384", "p384",
"rand", "rand 0.8.5",
"rpassword", "rpassword",
"rsa", "rsa",
"rust-crypto",
"rust_util", "rust_util",
"serde", "serde",
"serde_json", "serde_json",
@@ -1731,6 +1821,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
@@ -1961,7 +2057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96"
dependencies = [ dependencies = [
"curve25519-dalek", "curve25519-dalek",
"rand_core", "rand_core 0.6.4",
"serde", "serde",
"zeroize", "zeroize",
] ]
@@ -1993,7 +2089,7 @@ dependencies = [
"oid-registry", "oid-registry",
"rusticata-macros", "rusticata-macros",
"thiserror", "thiserror",
"time", "time 0.3.30",
] ]
[[package]] [[package]]
@@ -2017,7 +2113,7 @@ dependencies = [
"p384", "p384",
"pbkdf2", "pbkdf2",
"pcsc", "pcsc",
"rand_core", "rand_core 0.6.4",
"rsa", "rsa",
"secrecy", "secrecy",
"sha1", "sha1",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tiny-encrypt" name = "tiny-encrypt"
version = "0.4.2" version = "0.4.3"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
description = "A simple and tiny file encrypt tool" description = "A simple and tiny file encrypt tool"
@@ -24,6 +24,7 @@ rand = "0.8"
# reqwest = { version = "0.11", features = ["blocking", "rustls", "rustls-tls"] } # reqwest = { version = "0.11", features = ["blocking", "rustls", "rustls-tls"] }
rpassword = "7.2" rpassword = "7.2"
rsa = { version = "0.9", features = ["pem"] } rsa = { version = "0.9", features = ["pem"] }
rust-crypto = "0.2.36"
rust_util = "0.6" rust_util = "0.6"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"

View File

@@ -26,6 +26,7 @@ use crate::consts::{
use crate::crypto_aes::{aes_gcm_decrypt, try_aes_gcm_decrypt_with_salt}; use crate::crypto_aes::{aes_gcm_decrypt, try_aes_gcm_decrypt_with_salt};
use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta}; use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util::SecVec; use crate::util::SecVec;
use crate::util_digest::DigestWrite;
use crate::util_progress::Progress; use crate::util_progress::Progress;
use crate::wrap_key::WrapKey; use crate::wrap_key::WrapKey;
@@ -48,6 +49,12 @@ pub struct CmdDecrypt {
/// Direct print to the console, file must less than 10K /// Direct print to the console, file must less than 10K
#[arg(long)] #[arg(long)]
pub direct_print: bool, pub direct_print: bool,
/// Digest file
#[arg(long)]
pub digest_file: bool,
/// Digest algorithm (sha1, sha256[default], sha384, sha512 ...)
#[arg(long)]
pub digest_algorithm: Option<String>,
} }
pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> { pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
@@ -102,9 +109,15 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display); util_enc_file::read_tiny_encrypt_meta_and_normalize(&mut file_in), "Read file: {}, failed: {}", &path_display);
debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap()); debugging!("Found meta: {}", serde_json::to_string_pretty(&meta).unwrap());
let do_write_file_out = cmd_decrypt.skip_decrypt_file || cmd_decrypt.direct_print; let do_skip_file_out = cmd_decrypt.skip_decrypt_file || cmd_decrypt.direct_print || cmd_decrypt.digest_file;
let path_out = &path_display[0..path_display.len() - TINY_ENC_FILE_EXT.len()]; let path_out = &path_display[0..path_display.len() - TINY_ENC_FILE_EXT.len()];
if !do_write_file_out { util::require_file_not_exists(path_out)?; } if !do_skip_file_out { util::require_file_not_exists(path_out)?; }
let digest_algorithm = match &cmd_decrypt.digest_algorithm {
None => "sha256",
Some(algo) => algo.as_str(),
};
if cmd_decrypt.digest_file { DigestWrite::from_algo(digest_algorithm)?; } // QUICK CHECK
let selected_envelop = select_envelop(&meta, config)?; let selected_envelop = select_envelop(&meta, config)?;
@@ -140,10 +153,21 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
return Ok(meta.file_length); return Ok(meta.file_length);
} }
// Digest file
if cmd_decrypt.digest_file {
let mut digest_write = DigestWrite::from_algo(digest_algorithm)?;
let _ = decrypt_file(
&mut file_in, meta.file_length, &mut digest_write, &key.0, &nonce.0, meta.compress,
)?;
let digest = digest_write.digest();
success!("File digest {}: {}", digest_algorithm.to_uppercase(), hex::encode(digest));
return Ok(meta.file_length);
}
// Decrypt to file // Decrypt to file
let compressed_desc = iff!(meta.compress, " [compressed]", ""); let compressed_desc = iff!(meta.compress, " [compressed]", "");
let start = Instant::now(); let start = Instant::now();
let mut file_out = File::create(path_out)?; let mut file_out = File::create(path_out)?;
let _ = decrypt_file( let _ = decrypt_file(
&mut file_in, meta.file_length, &mut file_out, &key.0, &nonce.0, meta.compress, &mut file_in, meta.file_length, &mut file_out, &key.0, &nonce.0, meta.compress,
@@ -154,7 +178,7 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
let encrypt_duration = start.elapsed(); let encrypt_duration = start.elapsed();
debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis()); debugging!("Inner decrypt file{}: {} elapsed: {} ms", compressed_desc, path_display, encrypt_duration.as_millis());
if do_write_file_out & &cmd_decrypt.remove_file { util::remove_file_with_msg(path); } if do_skip_file_out & &cmd_decrypt.remove_file { util::remove_file_with_msg(path); }
Ok(meta.file_length) Ok(meta.file_length)
} }

View File

@@ -11,6 +11,7 @@ use crate::cmd_version::CmdVersion;
mod consts; mod consts;
mod util; mod util;
mod util_digest;
mod util_progress; mod util_progress;
mod util_piv; mod util_piv;
mod util_pgp; mod util_pgp;

71
src/util_digest.rs Normal file
View File

@@ -0,0 +1,71 @@
use std::io::Write;
use std::iter::repeat;
use crypto::digest::Digest;
use crypto::md5::Md5;
use crypto::ripemd160::Ripemd160;
use crypto::sha1::Sha1;
use crypto::sha2::{Sha224, Sha256, Sha384, Sha512, Sha512Trunc224, Sha512Trunc256};
use crypto::sha3::Sha3;
use crypto::whirlpool::Whirlpool;
use rust_util::{simple_error, XResult};
pub struct DigestWrite {
digest: Box<dyn Digest>,
}
impl Write for DigestWrite {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.digest.input(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
impl DigestWrite {
pub fn from_algo(algo: &str) -> XResult<Self> {
match get_digest_by_algorithm(algo) {
None => simple_error!("Unsupported algo: {}", algo),
Some(digest) => Ok(Self { digest })
}
}
pub fn digest(self) -> Vec<u8> {
let mut digest = self.digest;
let mut buf: Vec<u8> = repeat(0).take((digest.output_bits() + 7) / 8).collect();
digest.result(&mut buf);
buf
}
}
fn get_digest_by_algorithm(algo: &str) -> Option<Box<dyn Digest>> {
let algo = algo.to_uppercase();
match algo.as_str() {
"RIPEMD160" => Some(Box::new(Ripemd160::new())),
"WHIRLPOOL" => Some(Box::new(Whirlpool::new())),
// "BLAKE2S" => Some(Box::new(Blake2s::new(iff!(options.blake_len == 0_usize, 32, options.blake_len)))),
// "BLAKE2B" => Some(Box::new(Blake2b::new(iff!(options.blake_len == 0_usize, 64, options.blake_len)))),
"MD5" => Some(Box::new(Md5::new())),
"SHA1" | "SHA-1" => Some(Box::new(Sha1::new())),
"SHA224" | "SHA-224" => Some(Box::new(Sha224::new())),
"SHA256" | "SHA-256" => Some(Box::new(Sha256::new())),
"SHA384" | "SHA-384" => Some(Box::new(Sha384::new())),
"SHA512" | "SHA-512" => Some(Box::new(Sha512::new())),
"SHA512-224" => Some(Box::new(Sha512Trunc224::new())),
"SHA512-256" => Some(Box::new(Sha512Trunc256::new())),
"SHA3-224" => Some(Box::new(Sha3::sha3_224())),
"SHA3-256" => Some(Box::new(Sha3::sha3_256())),
"SHA3-384" => Some(Box::new(Sha3::sha3_384())),
"SHA3-512" => Some(Box::new(Sha3::sha3_512())),
"SHAKE-128" => Some(Box::new(Sha3::shake_128())),
"SHAKE-256" => Some(Box::new(Sha3::shake_256())),
"KECCAK-224" => Some(Box::new(Sha3::keccak224())),
"KECCAK-256" => Some(Box::new(Sha3::keccak256())),
"KECCAK-384" => Some(Box::new(Sha3::keccak384())),
"KECCAK-512" => Some(Box::new(Sha3::keccak512())),
_ => None,
}
}