feat: add decrypt-rs
This commit is contained in:
78
decrypt-rs/src/main.rs
Executable file
78
decrypt-rs/src/main.rs
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env runrs
|
||||
|
||||
//! ```cargo
|
||||
//! [dependencies]
|
||||
//! aes-gcm = { version = "0.10.1", features = ["zeroize", "stream"] }
|
||||
//! hex = "0.4.3"
|
||||
//! rust_util = "0.6.41"
|
||||
//! ```
|
||||
|
||||
use std::fs;
|
||||
use aes_gcm::aead::Aead;
|
||||
use aes_gcm::{Aes256Gcm, Key, KeyInit};
|
||||
|
||||
use rust_util::{failure_and_exit, information, opt_result, success, warning, XResult};
|
||||
|
||||
// see https://git.hatter.ink/hatter/crypto/src/branch/master/src/main/java/me/hatter/tools/crypto/stream/DecryptTool.java
|
||||
fn main() -> XResult<()> {
|
||||
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||
if args.len() != 3 {
|
||||
failure_and_exit!("crypt.rs <key-hex> <file-in> <file-out>");
|
||||
}
|
||||
let key_bytes = opt_result!(hex::decode(&args[0]), "Decode key failed: {}");
|
||||
if key_bytes.len() != 32 {
|
||||
failure_and_exit!("Key length must be 32 bytes, but is: {}", key_bytes.len());
|
||||
}
|
||||
|
||||
let file_in = &args[1];
|
||||
let file_out = &args[2];
|
||||
let file_in_meta = fs::metadata(file_in);
|
||||
|
||||
match file_in_meta {
|
||||
Err(_) => failure_and_exit!("File in not exists: {}", file_in),
|
||||
Ok(file_in_meta) => {
|
||||
let file_in_len = file_in_meta.len();
|
||||
if file_in_len < 100 * 1024 * 1024 {
|
||||
success!("File in: {}, size: {}", file_in, file_in_len);
|
||||
} else {
|
||||
warning!("File in: {}, size: {}", file_in, file_in_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_file_exists(file_out) {
|
||||
failure_and_exit!("File out exists: {}", file_out);
|
||||
}
|
||||
|
||||
information!("Reading file in: {}", file_in);
|
||||
let file_in_bytes = opt_result!(fs::read(&file_in), "Open file: {}, failed: {}", file_in);
|
||||
let magic = &file_in_bytes[0..4];
|
||||
let digest = &file_in_bytes[4..4 + 32];
|
||||
information!("Magic: {}", hex::encode(magic));
|
||||
information!("Key digest: {}", hex::encode(digest));
|
||||
|
||||
if hex::encode(magic) != "e2c50001" {
|
||||
failure_and_exit!("Magic number error: {}", hex::encode(magic));
|
||||
}
|
||||
|
||||
let mut nonce_bytes = [0_u8; 12];
|
||||
for i in 0..12 {
|
||||
nonce_bytes[i] = file_in_bytes[4 + 32 + i];
|
||||
}
|
||||
let file_in_bytes_content = &file_in_bytes[48..];
|
||||
|
||||
let key = Key::<Aes256Gcm>::from_slice(&key_bytes);
|
||||
let nonce = nonce_bytes.into();
|
||||
|
||||
let aes256_gcm = Aes256Gcm::new(&key);
|
||||
let decrypted = opt_result!(aes256_gcm.decrypt(&nonce, file_in_bytes_content), "Decrypt failed: {}");
|
||||
|
||||
information!("Writing file out: {}", file_out);
|
||||
opt_result!(fs::write(&file_out, decrypted), "Write file out: {}, failed: {}", file_out);
|
||||
|
||||
success!("Write file out succeed!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_file_exists(file: &str) -> bool {
|
||||
fs::metadata(file).is_ok()
|
||||
}
|
||||
Reference in New Issue
Block a user