Challenge 12 decrypt first block.

This commit is contained in:
2022-06-16 07:47:13 -04:00
parent e64cee1e2e
commit f9ddf4cccd
2 changed files with 70 additions and 12 deletions

View File

@@ -16,6 +16,10 @@ impl Bytes {
String::from(std::str::from_utf8(&v).unwrap())
}
pub fn first_block(&self, length: usize) -> Bytes {
Bytes(self.0[0..length].to_vec())
}
pub fn random(length: usize) -> Bytes {
Bytes(
(0..length)

View File

@@ -117,18 +117,72 @@ pub fn challenge12() {
cipher
}
let key = Bytes::random(16); // consistent but unknown key
// 1. Find key length
let mut v = vec![];
let initial_cipher_len = encryption_oracle(&key, &Bytes(v.to_vec())).0.len();
let mut new_cipher_len = initial_cipher_len;
while initial_cipher_len == new_cipher_len {
v.push(b'A');
let cipher = encryption_oracle(&key, &Bytes(v.to_vec()));
new_cipher_len = cipher.0.len();
fn get_length(key: &Bytes) -> usize {
// Detect cipher length
let mut v = vec![];
let initial_cipher_len = encryption_oracle(&key, &Bytes(v.to_vec())).0.len();
let mut new_cipher_len = initial_cipher_len;
while initial_cipher_len == new_cipher_len {
v.push(b'A');
let cipher = encryption_oracle(&key, &Bytes(v.to_vec()));
new_cipher_len = cipher.0.len();
}
let key_length = new_cipher_len - initial_cipher_len;
key_length
}
let key_length = new_cipher_len - initial_cipher_len;
println!("[xxxx] Challenge 12: key_length={}", key_length);
fn is_encryption_ecb(key: &Bytes) -> bool {
let data = Bytes::from_utf8("aaaabbbbccccddddaaaabbbbccccdddd");
let cipher = encryption_oracle(&key, &data);
if cipher.has_duplicated_cycle(16) {
true
} else {
false
}
}
fn decode_first_block(key: &Bytes) -> Bytes {
let block_size = 16;
let mut decoded_first_block = vec![];
for i in (0..16).rev() {
let mut padding_text = vec![b'A'; i];
let expected = encryption_oracle(&key, &Bytes(padding_text.to_vec()));
let expected_first_block = expected.first_block(block_size);
padding_text.append(&mut decoded_first_block.to_vec());
for i in 0..255 {
let mut text = padding_text.to_vec();
text.push(i);
let text = Bytes(text.to_vec());
let cipher_first_block = encryption_oracle(&key, &text).first_block(block_size);
if cipher_first_block.0 == expected_first_block.0 {
decoded_first_block.push(i);
break;
}
}
}
Bytes(decoded_first_block)
}
let key = Bytes::random(16); // consistent but unknown key
let key_length = get_length(&key); // 1. discover block size
assert_eq!(is_encryption_ecb(&key), true); // 2. confirm oracle uses ecb
let first_block = decode_first_block(&key); // 3.-6.
println!(
"[xxxx] Challenge 12: key_length={}, first_block={}",
key_length,
first_block.to_utf8()
);
// Just some experiments to see how openssl does padding
// println!(
// "len={}",
// ecb::encrypt(
// &Bytes::from_utf8("aaaabbbbccccdddd"),
// &Bytes::from_utf8("aaaabbbbccccddddaaaabbbbccccdddd")
// )
// .0
// .len()
// );
}