From cc18a545a87ca616f05114d174690e5cc9614669 Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Tue, 16 Jul 2024 17:24:33 +0900 Subject: Optimize encryption - Add archive for testing encryption of compressed files - Implement incorrect password check - Use custom crc32 function --- src/zip/encryption.rs | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) (limited to 'src/zip/encryption.rs') diff --git a/src/zip/encryption.rs b/src/zip/encryption.rs index 84e30d5..28a6bdb 100644 --- a/src/zip/encryption.rs +++ b/src/zip/encryption.rs @@ -1,12 +1,35 @@ use crate::utils::ReadUtils; -use crate::zip::ZipResult; -use crc32fast::Hasher; +use crate::zip::{ZipError, ZipResult}; use std::io::{Read, Result as IoResult}; -fn crc32(byte: u8, crc32: u32) -> u32 { - let mut hasher = Hasher::new_with_initial(crc32 ^ 0xFFFFFFFF); - hasher.update(&[byte]); - hasher.finalize() ^ 0xFFFFFFFF +const TABLE: [u32; 256] = generate_table(); + +const fn generate_table() -> [u32; 256] { + let mut table = [0; 256]; + + let mut b = 0; + while b <= 255 { + let mut crc = b as u32; + + let mut i = 0; + while i < 8 { + if (crc & 1) > 0 { + crc = (crc >> 1) ^ 0xEDB88320 + } else { + crc >>= 1 + } + i += 1; + } + + table[b] = crc; + b += 1 + } + + table +} + +fn crc32(byte: u8, crc: u32) -> u32 { + (crc >> 8) ^ TABLE[((crc & 0xFF) as u8 ^ byte) as usize] } pub struct WeakDecoder { @@ -17,7 +40,7 @@ pub struct WeakDecoder { } impl WeakDecoder { - pub fn new(io: Io, password: &str) -> ZipResult { + pub fn new(io: Io, check: u8, password: &[u8]) -> ZipResult { let mut decoder = Self { key0: 305419896, key1: 591751049, @@ -25,11 +48,14 @@ impl WeakDecoder { io, }; - for c in password.chars() { - decoder.update_keys(c as u8) + for c in password { + decoder.update_keys(*c) } let buf = decoder.read_arr::<12>()?; + if check != buf[11] { + return Err(ZipError::IncorrectPassword.into()); + } Ok(decoder) } @@ -46,7 +72,9 @@ impl WeakDecoder { fn decode_byte(&mut self, byte: u8) -> u8 { let key = self.key2 | 2; - byte ^ (((key * (key ^ 1)) >> 8) as u8) + let byte = byte ^ ((key * (key ^ 1)) >> 8) as u8; + self.update_keys(byte); + byte } } @@ -55,7 +83,6 @@ impl Read for WeakDecoder { let bytes = self.io.read(buf)?; for i in 0..bytes { buf[i] = self.decode_byte(buf[i]); - self.update_keys(buf[i]) } Ok(bytes) } -- cgit v1.2.3