feat: decrypt supports compress
This commit is contained in:
@@ -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"
|
||||
|
||||
47
README.md
47
README.md
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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: {}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user