diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-07-16 17:24:33 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-07-16 17:24:33 +0900 |
| commit | cc18a545a87ca616f05114d174690e5cc9614669 (patch) | |
| tree | 51ec845115754bb1d8b41d82e5349db5343a40ec /src/zip/encryption.rs | |
| parent | a83767f9fbd51df654901b52bdba7838f6a10bf9 (diff) | |
| download | archivator-cc18a545a87ca616f05114d174690e5cc9614669.tar.gz archivator-cc18a545a87ca616f05114d174690e5cc9614669.zip | |
Optimize encryption
- Add archive for testing encryption of compressed files
- Implement incorrect password check
- Use custom crc32 function
Diffstat (limited to 'src/zip/encryption.rs')
| -rw-r--r-- | src/zip/encryption.rs | 49 |
1 files changed, 38 insertions, 11 deletions
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 @@ | |||
| 1 | use crate::utils::ReadUtils; | 1 | use crate::utils::ReadUtils; |
| 2 | use crate::zip::ZipResult; | 2 | use crate::zip::{ZipError, ZipResult}; |
| 3 | use crc32fast::Hasher; | ||
| 4 | use std::io::{Read, Result as IoResult}; | 3 | use std::io::{Read, Result as IoResult}; |
| 5 | 4 | ||
| 6 | fn crc32(byte: u8, crc32: u32) -> u32 { | 5 | const TABLE: [u32; 256] = generate_table(); |
| 7 | let mut hasher = Hasher::new_with_initial(crc32 ^ 0xFFFFFFFF); | 6 | |
| 8 | hasher.update(&[byte]); | 7 | const fn generate_table() -> [u32; 256] { |
| 9 | hasher.finalize() ^ 0xFFFFFFFF | 8 | let mut table = [0; 256]; |
| 9 | |||
| 10 | let mut b = 0; | ||
| 11 | while b <= 255 { | ||
| 12 | let mut crc = b as u32; | ||
| 13 | |||
| 14 | let mut i = 0; | ||
| 15 | while i < 8 { | ||
| 16 | if (crc & 1) > 0 { | ||
| 17 | crc = (crc >> 1) ^ 0xEDB88320 | ||
| 18 | } else { | ||
| 19 | crc >>= 1 | ||
| 20 | } | ||
| 21 | i += 1; | ||
| 22 | } | ||
| 23 | |||
| 24 | table[b] = crc; | ||
| 25 | b += 1 | ||
| 26 | } | ||
| 27 | |||
| 28 | table | ||
| 29 | } | ||
| 30 | |||
| 31 | fn crc32(byte: u8, crc: u32) -> u32 { | ||
| 32 | (crc >> 8) ^ TABLE[((crc & 0xFF) as u8 ^ byte) as usize] | ||
| 10 | } | 33 | } |
| 11 | 34 | ||
| 12 | pub struct WeakDecoder<Io: Read> { | 35 | pub struct WeakDecoder<Io: Read> { |
| @@ -17,7 +40,7 @@ pub struct WeakDecoder<Io: Read> { | |||
| 17 | } | 40 | } |
| 18 | 41 | ||
| 19 | impl<Io: Read> WeakDecoder<Io> { | 42 | impl<Io: Read> WeakDecoder<Io> { |
| 20 | pub fn new(io: Io, password: &str) -> ZipResult<Self> { | 43 | pub fn new(io: Io, check: u8, password: &[u8]) -> ZipResult<Self> { |
| 21 | let mut decoder = Self { | 44 | let mut decoder = Self { |
| 22 | key0: 305419896, | 45 | key0: 305419896, |
| 23 | key1: 591751049, | 46 | key1: 591751049, |
| @@ -25,11 +48,14 @@ impl<Io: Read> WeakDecoder<Io> { | |||
| 25 | io, | 48 | io, |
| 26 | }; | 49 | }; |
| 27 | 50 | ||
| 28 | for c in password.chars() { | 51 | for c in password { |
| 29 | decoder.update_keys(c as u8) | 52 | decoder.update_keys(*c) |
| 30 | } | 53 | } |
| 31 | 54 | ||
| 32 | let buf = decoder.read_arr::<12>()?; | 55 | let buf = decoder.read_arr::<12>()?; |
| 56 | if check != buf[11] { | ||
| 57 | return Err(ZipError::IncorrectPassword.into()); | ||
| 58 | } | ||
| 33 | 59 | ||
| 34 | Ok(decoder) | 60 | Ok(decoder) |
| 35 | } | 61 | } |
| @@ -46,7 +72,9 @@ impl<Io: Read> WeakDecoder<Io> { | |||
| 46 | 72 | ||
| 47 | fn decode_byte(&mut self, byte: u8) -> u8 { | 73 | fn decode_byte(&mut self, byte: u8) -> u8 { |
| 48 | let key = self.key2 | 2; | 74 | let key = self.key2 | 2; |
| 49 | byte ^ (((key * (key ^ 1)) >> 8) as u8) | 75 | let byte = byte ^ ((key * (key ^ 1)) >> 8) as u8; |
| 76 | self.update_keys(byte); | ||
| 77 | byte | ||
| 50 | } | 78 | } |
| 51 | } | 79 | } |
| 52 | 80 | ||
| @@ -55,7 +83,6 @@ impl<Io: Read> Read for WeakDecoder<Io> { | |||
| 55 | let bytes = self.io.read(buf)?; | 83 | let bytes = self.io.read(buf)?; |
| 56 | for i in 0..bytes { | 84 | for i in 0..bytes { |
| 57 | buf[i] = self.decode_byte(buf[i]); | 85 | buf[i] = self.decode_byte(buf[i]); |
| 58 | self.update_keys(buf[i]) | ||
| 59 | } | 86 | } |
| 60 | Ok(bytes) | 87 | Ok(bytes) |
| 61 | } | 88 | } |
