feat: decrypt supports compress
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tiny-encrypt"
|
name = "tiny-encrypt"
|
||||||
version = "0.0.2"
|
version = "0.0.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"
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -5,13 +5,13 @@ Tiny encrypt for Rust
|
|||||||
> Tiny encrypt spec see: https://git.hatter.ink/hatter/tiny-encrypt-java
|
> Tiny encrypt spec see: https://git.hatter.ink/hatter/tiny-encrypt-java
|
||||||
|
|
||||||
TODOs:
|
TODOs:
|
||||||
* Decrypt supports compress
|
|
||||||
* Encrypt subcommand
|
|
||||||
|
|
||||||
|
* Encrypt subcommand
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Encrypt config `~/.tinyencrypt/config-rs.json`:
|
Encrypt config `~/.tinyencrypt/config-rs.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"envelops": [
|
"envelops": [
|
||||||
@@ -29,8 +29,13 @@ Encrypt config `~/.tinyencrypt/config-rs.json`:
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"default": ["KID-1", "KID-2"],
|
"default": [
|
||||||
"leve2": ["KID-2"]
|
"KID-1",
|
||||||
}
|
"KID-2"
|
||||||
|
],
|
||||||
|
"leve2": [
|
||||||
|
"KID-2"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use yubikey::YubiKey;
|
|||||||
|
|
||||||
use crate::{file, util};
|
use crate::{file, util};
|
||||||
use crate::card::get_card;
|
use crate::card::get_card;
|
||||||
|
use crate::compress::GzStreamDecoder;
|
||||||
use crate::crypto::aes_gcm_decrypt;
|
use crate::crypto::aes_gcm_decrypt;
|
||||||
use crate::spec::{TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
|
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};
|
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));
|
debugging!("Decrypt nonce: {}", hex::encode(&nonce));
|
||||||
|
|
||||||
let mut file_out = File::create(path_out)?;
|
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(())
|
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 total_len = 0;
|
||||||
let mut buffer = [0u8; 1024 * 8];
|
let mut buffer = [0u8; 1024 * 8];
|
||||||
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
|
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
|
||||||
let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, &nonce);
|
let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, &nonce);
|
||||||
|
let mut gz_decoder = GzStreamDecoder::new();
|
||||||
loop {
|
loop {
|
||||||
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
|
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
let last_block = opt_result!(decryptor.finalize(), "Decrypt file failed: {}");
|
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: {}");
|
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
|
||||||
success!("Decrypt finished, total bytes: {}", total_len);
|
success!("Decrypt finished, total bytes: {}", total_len);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
total_len += len;
|
total_len += len;
|
||||||
let decrypted = decryptor.update(&buffer[0..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: {}");
|
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user