Skip to main content

dec_cryptor/
decryptor.rs

1use std::fs::File;
2use std::io::{Read, Write, BufReader, BufWriter, Seek, SeekFrom};
3use std::path::Path;
4use aes::Aes256;
5use ctr::Ctr128BE;
6use ctr::cipher::{KeyIvInit, StreamCipher};
7use crate::crypto_utils::*;
8use crate::progress_utils::*;
9use crate::key_derivation;
10use crate::hmac_validator::HmacValidator;
11
12type Aes256Ctr = Ctr128BE<Aes256>;
13
14pub fn check_version(input_file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
15    let input_path = Path::new(input_file_path);
16    
17    // 打开文件并读取文件头信息
18    let mut file = File::open(input_path)?;
19    let mut magic_number_bytes = vec![0u8; MAGIC_NUMBER.len()];
20    file.read_exact(&mut magic_number_bytes)?;
21    
22    // 验证魔数
23    if magic_number_bytes != MAGIC_NUMBER.as_bytes() {
24        return Err("无效的加密文件格式".into());
25    }
26    
27    // 读取版本字节
28    let mut version = [0u8; 1];
29    file.read_exact(&mut version)?;
30    if version[0] != VERSION_SIGN {
31        return Err(format!("不支持的文件版本: {}", version[0]).into());
32    }
33    
34    Ok(())
35}
36
37pub fn decrypt_with_mode(input_file_path: &str, output_file_path: &str, password: &str) -> Result<(), Box<dyn std::error::Error>> {
38    let input_path = Path::new(input_file_path);
39    let output_path = Path::new(output_file_path);
40
41    if !input_path.exists() || !input_path.is_file() {
42        return Err(format!("输入文件不存在: {}", input_file_path).into());
43    }
44    
45    // 启动计时器
46    let start_time = start_timer();
47    
48    // 读取文件头信息(使用缓冲读)
49    let mut file = BufReader::with_capacity(BUFFER_SIZE, File::open(input_path)?);
50    
51    // 跳过魔数和版本字节
52    file.seek(SeekFrom::Start((MAGIC_NUMBER.len() + 1) as u64))?;
53    
54    // 读取盐和IV
55    let mut salt = vec![0u8; SALT_LENGTH];
56    file.read_exact(&mut salt)?;
57    let mut iv = vec![0u8; IV_LENGTH];
58    file.read_exact(&mut iv)?;
59    
60    // 使用Argon2派生主密钥
61    let master_key = key_derivation::derive_master_key(password.as_bytes(), &salt)?;
62    
63    // 使用HKDF派生加密密钥和HMAC密钥
64    let (encryption_key, hmac_key) = key_derivation::derive_encryption_and_hmac_keys(&master_key)?;
65    
66    // 计算文件总长度和文件头长度
67    let total_file_length = input_path.metadata()?.len();
68    let header_length = (MAGIC_NUMBER.len() + 1 + SALT_LENGTH + IV_LENGTH) as u64;
69    let hmac_length = 32u64; // HMAC-SHA256的长度
70    let encrypted_data_length = total_file_length - header_length - hmac_length;
71    
72    // 创建输出文件(放大写缓冲)
73    let mut output_file = File::create(output_path)?;
74    let mut writer = BufWriter::with_capacity(BUFFER_SIZE, &mut output_file);
75    
76    // parts 模式:仅当 parts==1 时持有单流解密器;否则使用并行处理
77    let parallel_parts = get_parts();
78
79    let mut single_cipher = if parallel_parts == 1 {
80        Some(Aes256Ctr::new(encryption_key.as_slice().into(), iv.as_slice().into()))
81    } else { None };
82    
83    // 创建HMAC计算器
84    let mut hmac = HmacValidator::new(&hmac_key)?;
85    
86    // 流式解密数据
87    let mut buffer = vec![0u8; BUFFER_SIZE];
88    let mut total_read = 0;
89    
90    while total_read < encrypted_data_length {
91        let bytes_to_read = std::cmp::min(BUFFER_SIZE as u64, encrypted_data_length - total_read) as usize;
92        let bytes_read = file.read(&mut buffer[..bytes_to_read])?;
93        
94        if bytes_read == 0 {
95            break;
96        }
97        
98        let chunk = &mut buffer[..bytes_read];
99        
100        // 更新HMAC(对密文计算)
101        hmac.update(chunk);
102
103        if parallel_parts == 1 {
104            if let Some(cipher) = &mut single_cipher { cipher.apply_keystream(chunk); }
105        } else {
106            crate::parallel_handler::ctr_apply_in_parts(
107                encryption_key.as_slice(),
108                iv.as_slice(),
109                chunk,
110                total_read as usize
111            ).map_err(|e| format!("parallel decrypt error: {}", e))?;
112        }
113        
114        // 写入解密后的数据
115        writer.write_all(chunk)?;
116        
117        total_read += bytes_read as u64;
118        
119        // 更新进度显示
120        update_progress(total_read, encrypted_data_length);
121    }
122    
123    // 读取存储的HMAC
124    let mut stored_hmac = vec![0u8; hmac_length as usize];
125    file.read_exact(&mut stored_hmac)?;
126    
127    // 验证HMAC
128    hmac.verify(&stored_hmac)?;
129    
130    writer.flush()?;
131    
132    // 显示进度完成
133    let duration = start_time.elapsed();
134    update_progress(encrypted_data_length, encrypted_data_length);
135    println!("\u{001B}[0mDEC!: Done in {}", format_duration(duration));
136    
137    Ok(())
138}