RC4 is a stream cipher that was created by Ron Rivest, and created in 1987. It is generally a fast cipher, and where we create a key stream based on a password. RC4 was used in WEP (Wired Equivalent Privacy), and where a small IV value caused serious security problems. The key length can vary from one to 256 bytes, and is used to create an initial 256-byte state vector (S). The output is basically X-OR'ed one bit at a time with the keystream, and the plaintext is recovered by X-OR'ing the cipherstream with the keystream. As we are using a stream cipher, there is no need for padding, and where the ciphertext stream size will be the same as the plaintext length [RC4 Python code].
RC4 in Rust |
Code
First we create the with:
cargo new rc4
We then go into the rc4 folder, and add the following to the cargo.toml file:
[package] name = "rc" 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" hex="0.4.3" base64="0.13.0" rustc-serialize = "0.3"
In this case we will use RC4:
use crypto::rc4::Rc4; use crypto::symmetriccipher::SynchronousStreamCipher; use std::env; use core::str; use std::iter::repeat; fn main() { let mut mykey="hello"; let mut plain="hello"; let args: Vec<String> = env::args().collect(); if args.len() >1 { mykey = args[1].as_str();} if args.len() >2 { plain = args[2].as_str();} println!("== RC4=="); println!("Message: {:?}",plain); println!("Key: {:?}",mykey); let mut output: Vec= repeat(0).take(plain.len()).collect(); let mut rc4 = Rc4::new(mykey.as_bytes()); let mut result: Vec = repeat(0).take(plain.len()).collect(); rc4.process(plain.as_bytes(), &mut result); println!("\nEncrypted (Hex): {}",hex::encode(result.clone())); println!("Encrypted (Base-64): {}",base64::encode(result.clone())); let mut rc4 = Rc4::new(mykey.as_bytes()); let mut outplain: Vec = repeat(0).take(plain.len()).collect(); rc4.process(&mut result[..], &mut outplain); println!("\nDecrypted (hex) {}",hex::encode(outplain.clone())); println!("Decrypted (ASCII): {:?}",str::from_utf8(&outplain[..]).unwrap()); }
Finally we simply build with:
cargo build
A sample run is:
== RC4== Message: "Hello World!" Key: "My key" Encrypted (Hex): 775bf38e75d3ec6bf00c5223 Encrypted (Base-64): d1vzjnXT7GvwDFIj Decrypted (hex) 48656c6c6f20576f726c6421 Decrypted (ASCII): "Hello World!"