feat: decrypt supports compress

This commit is contained in:
2023-09-09 20:38:04 +08:00
parent 7fb94fdb07
commit 514d5888a4
3 changed files with 44 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "tiny-encrypt"
version = "0.0.2"
version = "0.0.3"
edition = "2021"
license = "MIT"
description = "A simple and tiny file encrypt tool"

View File

@@ -5,32 +5,37 @@ Tiny encrypt for Rust
> Tiny encrypt spec see: https://git.hatter.ink/hatter/tiny-encrypt-java
TODOs:
* Decrypt supports compress
* Encrypt subcommand
* Encrypt subcommand
<br>
Encrypt config `~/.tinyencrypt/config-rs.json`:
```json
{
"envelops": [
{
"type": "pgp",
"kid": "KID-1",
"desc": "this is key 001",
"publicPart": "----- BEGIN OPENPGP ..."
},
{
"type": "ecdh",
"kid": "KID-2",
"desc": "this is key 002",
"publicPart": "04..."
}
],
"profiles": {
"default": ["KID-1", "KID-2"],
"leve2": ["KID-2"]
}
}
"envelops": [
{
"type": "pgp",
"kid": "KID-1",
"desc": "this is key 001",
"publicPart": "----- BEGIN OPENPGP ..."
},
{
"type": "ecdh",
"kid": "KID-2",
"desc": "this is key 002",
"publicPart": "04..."
}
],
"profiles": {
"default": [
"KID-1",
"KID-2"
],
"leve2": [
"KID-2"
]
}
}
```

View File

@@ -15,6 +15,7 @@ use yubikey::YubiKey;
use crate::{file, util};
use crate::card::get_card;
use crate::compress::GzStreamDecoder;
use crate::crypto::aes_gcm_decrypt;
use crate::spec::{TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util::{decode_base64, decode_base64_url_no_pad, ENC_AES256_GCM_P256, simple_kdf, TINY_ENC_FILE_EXT};
@@ -66,26 +67,40 @@ pub fn decrypt_single(path: &PathBuf, pin: &Option<String>, slot: &Option<String
debugging!("Decrypt nonce: {}", hex::encode(&nonce));
let mut file_out = File::create(path_out)?;
let _ = decrypt_file(&mut file_in, &mut file_out, &key, &nonce)?;
let _ = decrypt_file(&mut file_in, &mut file_out, &key, &nonce, meta.compress)?;
Ok(())
}
fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8]) -> XResult<usize> {
fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult<usize> {
let mut total_len = 0;
let mut buffer = [0u8; 1024 * 8];
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, &nonce);
let mut gz_decoder = GzStreamDecoder::new();
loop {
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
if len == 0 {
let last_block = opt_result!(decryptor.finalize(), "Decrypt file failed: {}");
let last_block = if compress {
let mut decompressed = opt_result!(gz_decoder.update(&last_block), "Decompress file failed: {}");
let last_decompressed_buffer = opt_result!(gz_decoder.finalize(), "Decompress file failed: {}");
decompressed.extend_from_slice(&last_decompressed_buffer);
decompressed
} else {
last_block
};
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
success!("Decrypt finished, total bytes: {}", total_len);
break;
} else {
total_len += len;
let decrypted = decryptor.update(&buffer[0..len]);
let decrypted = if compress {
opt_result!(gz_decoder.update(&decrypted), "Decompress file failed: {}")
} else {
decrypted
};
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
}
}