From c49225f47da16937410a6dd5d5c3ec3e86ca39f6 Mon Sep 17 00:00:00 2001 From: Pedro de Oliveira Date: Wed, 17 May 2023 20:20:41 +0100 Subject: [PATCH] First commit --- .gitignore | 3 ++ Cargo.lock | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 ++++ src/main.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..471f9bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/.idea/ +rfish.iml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0a7b6e4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,133 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +dependencies = [ + "libc", + "rand 0.4.6", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rfish" +version = "0.1.0" +dependencies = [ + "rust-crypto", +] + +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +dependencies = [ + "gcc", + "libc", + "rand 0.3.23", + "rustc-serialize", + "time", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi", + "winapi", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0bae876 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rfish" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rust-crypto = "0.2.36" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..14b48e9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,128 @@ +extern crate crypto; + +use crypto::blowfish::Blowfish; +use crypto::symmetriccipher::{BlockDecryptor, BlockEncryptor}; + +struct Base64 {} + +impl Base64 { + const BASE64_CUSTOM_DICTIONARY: [char; 64] = [ + '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + ]; + + fn load32_be(p: &[u8]) -> u32 { + u32::from_be_bytes([p[0], p[1], p[2], p[3]]) + } + + fn store32_be(p: &mut [u8], v: u32) { + let bytes = v.to_be_bytes(); + p.copy_from_slice(&bytes[..p.len()]); + } + + fn base64dec(c: char) -> u32 { + for (i, b64_char) in Self::BASE64_CUSTOM_DICTIONARY.iter().enumerate() { + if *b64_char == c { + return i as u32; + } + } + 0 + } + + pub fn encode(input: &[u8]) -> String { + let mut dest = vec![]; + let input_blocks = input.chunks_exact(8); + for block in input_blocks { + let mut value = Self::load32_be(&block[4..8]); + for _ in 0..6 { + dest.push(Self::BASE64_CUSTOM_DICTIONARY[(value & 0x3F) as usize]); + value >>= 6; + } + let mut value = Self::load32_be(&block[0..4]); + for _ in 0..6 { + dest.push(Self::BASE64_CUSTOM_DICTIONARY[(value & 0x3F) as usize]); + value >>= 6; + } + } + dest.iter().collect() + } + + pub fn decode(input: &[u8]) -> Vec { + let mut output: Vec = vec![]; + + for block in input.chunks_exact(12) { + let mut v: u32 = 0; + let mut output_block: [u8; 8] = [0u8; 8]; + for i in 0..6 { + v |= Self::base64dec(block[i] as char) << (i * 6); + } + Self::store32_be(&mut output_block[4..], v); + v = 0; + for i in 0..6 { + v |= Self::base64dec(block[i + 6] as char) << (i * 6); + } + Self::store32_be(&mut output_block[..4], v); + output.extend_from_slice(&output_block); + } + output + } +} + +struct Fish { + key: Vec, +} + +impl Fish { + pub fn new(key: &[u8]) -> Fish { + Fish { key: key.to_vec() } + } + + pub fn encrypt(&self, input: &[u8]) -> String { + let mut output: Vec = vec![]; + let cipher = Blowfish::new(&self.key); + let input_blocks = input.chunks(8); + for block in input_blocks { + let mut block_with_padding = [0u8; 8]; + let mut output_block = [0u8; 8]; + for (i, &byte) in block.iter().enumerate() { + block_with_padding[i] = byte; + } + cipher.encrypt_block(&block_with_padding, &mut output_block); + output.extend_from_slice(&output_block); + } + Base64::encode(&output) + } + + pub fn decrypt(&self, input: &[u8]) -> String { + let mut output: Vec = vec![]; + let cipher = Blowfish::new(&self.key); + let decoded_input = Base64::decode(input); + let input_blocks = decoded_input.chunks(8); + for block in input_blocks { + let mut output_block = [0u8; 8]; + cipher.decrypt_block(block, &mut output_block); + let vec_char: Vec = output_block.into_iter().map(|byte| byte as char).collect(); + output.extend_from_slice(&vec_char); + } + output + .iter() + .collect::() + .trim_end_matches('\0') + .to_string() + } +} + +fn main() { + let key = b"chaveULTRAgulosa"; + let input = b"Viva o Benfica"; + + let fish = Fish::new(key); + + let encrypted = fish.encrypt(input); + println!("Encrypted: {:?}", encrypted); + + let decrypted = fish.decrypt(encrypted.as_bytes()); + println!("Decrypted: {:?}", decrypted); +}