cryptopals

Matasano's cryptopals challenges (cryptopals.com).
Log | Files | Refs | README | LICENSE

commit 3200096b293e28c8b28c139fc86b09a3bbba314a
parent daa64a220b5597935d2bacf48e839fc46618cf64
Author: Jared Tobin <jared@jtobin.ca>
Date:   Wed, 30 Aug 2017 10:27:47 +1200

Updates.

Diffstat:
MCargo.toml | 1+
Mdocs/s1.md | 3++-
Mlib/aes_ecb/src/main.rs | 8+++++---
Msrc/main.rs | 2++
Msrc/s1c1.rs | 2+-
Msrc/s1c2.rs | 1+
Asrc/s1c7.rs | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -7,4 +7,5 @@ authors = ["Jared Tobin <jared@jtobin.ca>"] base64 = "0.6.0" clap = "2.26.0" hex = "0.2.0" +openssl = "0.9.11" diff --git a/docs/s1.md b/docs/s1.md @@ -84,7 +84,8 @@ hits, but it doesn't seem to decrypt to anything. Can check this by grabbing the result under 'INPUT' and xor-ing it again: - $ xxd -r -p <<< $INPUT | ./bin/repeating_key_xor ICE | xxd -r -p | less + $ xxd -r -p <<< $INPUT | ./bin/repeating_key_xor ICE | xxd -r -p | tail -c +2 + Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal #### 1.6 diff --git a/lib/aes_ecb/src/main.rs b/lib/aes_ecb/src/main.rs @@ -15,17 +15,19 @@ fn crypt(cipher: Cipher, iv: Option<&[u8]>, input : Vec<u8>) -> Vec<u8> { - let input_len = input.len(); + let result_len = input.len() + cipher.key_len(); + let mut result = vec![0u8; result_len]; let mut crypter = new_crypter_unpadded(cipher, mode, key, iv); - let mut result = vec![0u8; input_len + cipher.key_len()]; let decrypted_len = match crypter.update(&input, result.as_mut_slice()) { Ok(val) => val, Err(err) => panic!("couldn't calculate len: {}", err) }; - (&result[0..decrypted_len]).to_vec() + let return_slice = &result[0..decrypted_len]; + + return_slice.to_vec() } fn new_crypter_unpadded( diff --git a/src/main.rs b/src/main.rs @@ -2,9 +2,11 @@ mod s1c1; mod s1c2; mod s1c3; +mod s1c7; fn main() { println!("s1c1:\n{}\n", s1c1::s1c1()); println!("s1c2:\n{}\n", s1c2::s1c2()); println!("s1c3:\n{}\n", s1c3::s1c3()); + println!("s1c7:\n{}\n", s1c7::s1c7()); } diff --git a/src/s1c1.rs b/src/s1c1.rs @@ -1,6 +1,6 @@ -extern crate hex; extern crate base64; +extern crate hex; use self::hex::{FromHex, FromHexError}; use std::process; diff --git a/src/s1c2.rs b/src/s1c2.rs @@ -7,6 +7,7 @@ const TARGET: &str = "1c0111001f010100061a024b53535009181c"; const PARTNER: &str = "686974207468652062756c6c277320657965"; fn fixed_xor(target: &str, partner: &str) -> String { + assert_eq!(target.len(), partner.len()); let mut l: Vec<u8> = FromHex::from_hex(&target).unwrap(); diff --git a/src/s1c7.rs b/src/s1c7.rs @@ -0,0 +1,77 @@ + +extern crate base64; +extern crate openssl; + +use self::openssl::symm::{Cipher, Crypter, Mode}; +use std::io::prelude::Read; +use std::fs::File; +use std::str; +use std::string::String; + +fn new_crypter_unpadded( + cipher: Cipher, + mode: Mode, + key: &[u8], + iv: Option<&[u8]> + ) -> Crypter { + + let mut crypter = Crypter::new(cipher, mode, key, iv).unwrap(); + + crypter.pad(false); + + crypter +} + +fn aes_128_ecb_crypt(mode: Mode, key: &[u8], content: &[u8]) -> Vec<u8> { + let cipher = Cipher::aes_128_ecb(); + let iv = None; + let bsize = content.len() + cipher.key_len(); + let mut buffer = vec![0; bsize]; + + let mut crypter = new_crypter_unpadded(cipher, mode, key, iv); + + let crypted_len = crypter.update(content, &mut buffer).unwrap(); + let finalized_len = crypter.finalize(&mut buffer).unwrap(); + + buffer[0..crypted_len + finalized_len].to_vec() +} + +pub fn aes_128_ecb_decrypt(key: &str, ciphertext: &str) -> String { + let key: Vec<u8> = base64::decode(&key).unwrap(); + let ciphertext: Vec<u8> = base64::decode(&ciphertext).unwrap(); + + let message = aes_128_ecb_crypt(Mode::Decrypt, &key[..], &ciphertext[..]); + + base64::encode(&message) +} + +pub fn aes_128_ecb_encrypt(key: &str, message: &str) -> String { + let key: Vec<u8> = base64::decode(&key).unwrap(); + let message: Vec<u8> = base64::decode(&message).unwrap(); + + let ciphertext = aes_128_ecb_crypt(Mode::Encrypt, &key[..], &message[..]); + + base64::encode(&ciphertext) +} + +pub fn s1c7() -> String { + let key = base64::encode("YELLOW SUBMARINE"); + let mut handle = File::open("data/s1/q7_input.txt").unwrap(); + let mut buffer = String::new(); + + let bsize = handle.read_to_string(&mut buffer); + + if let Err(err) = bsize { + panic!("{}", err); + } + + let trimmed: String = buffer.chars() + .filter(|&char| char != '\n') + .collect(); + + let decrypted = aes_128_ecb_decrypt(&key, &trimmed); + let decrypted = base64::decode(&decrypted).unwrap(); + + String::from_utf8(decrypted).unwrap() +} +