Start with challenge 17.

This commit is contained in:
2022-07-02 10:42:36 -04:00
parent 956d75ab4e
commit d1be95cbe1
4 changed files with 68 additions and 20 deletions

View File

@@ -146,10 +146,10 @@ pub fn challenge12() {
fn decode(key: &Bytes) -> Bytes {
let block_size = get_block_size(&key);
let block_count = encryption_oracle(&key, &Bytes(vec![])).0.len() / block_size;
let mut clear_text = vec![];
let mut cleartext = vec![];
for block_index in 0..block_count {
let mut clear_text_block = vec![];
let mut cleartext_block = vec![];
for padding_length in (0..block_size).rev() {
let padding_text = vec![b'-'; padding_length];
let expected = encryption_oracle(&key, &Bytes(padding_text.to_vec()));
@@ -158,11 +158,11 @@ pub fn challenge12() {
let mut known_text = if block_index == 0 {
padding_text.to_vec()
} else {
let clear_text_offset =
let cleartext_offset =
((block_index - 1) * block_size) + (block_size - padding_length);
clear_text[clear_text_offset..(clear_text_offset + padding_length)].to_vec()
cleartext[cleartext_offset..(cleartext_offset + padding_length)].to_vec()
};
known_text.append(&mut clear_text_block.to_vec());
known_text.append(&mut cleartext_block.to_vec());
for i in 0..255 {
let mut guess_text = known_text.to_vec();
@@ -170,27 +170,27 @@ pub fn challenge12() {
let cipher_block =
encryption_oracle(&key, &Bytes(guess_text)).get_block(0, block_size);
if cipher_block.0 == expected_block.0 {
clear_text_block.push(i);
cleartext_block.push(i);
break;
}
}
}
clear_text.append(&mut clear_text_block);
cleartext.append(&mut cleartext_block);
}
Bytes(clear_text)
Bytes(cleartext)
}
let key = Bytes::random(16); // consistent but unknown key
assert_eq!(get_block_size(&key), 16); // 1. discover block size
assert_eq!(is_encryption_ecb(&key), true); // 2. confirm oracle uses ecb
let roundtrip_text = decode(&key); // 3.-6.
let clear_text = read("data/12.txt");
let cleartext = read("data/12.txt");
// 138 (instead of 139); I think we get one additional byte because we guess
// the first padding byte. The right approach would be to remove the last
// byte, encrypt it, and then compare it to the result of the encryption
// oracle, but this approach is fine too.
assert_eq!(roundtrip_text.0[..138], clear_text.0);
assert_eq!(roundtrip_text.0[..138], cleartext.0);
println!(
"[okay] Challenge 12: {}",
roundtrip_text.to_utf8()[..17].to_string()
@@ -331,7 +331,7 @@ pub fn challenge14() {
let prefix_padding = Bytes(vec![b'a'; prefix_padding_size]);
let block_count = encryption_oracle(&prefix, &key, &prefix_padding).len() / block_size;
let first_block_index = (prefix_size + prefix_padding_size) / block_size;
let mut clear_text = vec![];
let mut cleartext = vec![];
// AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key)
// rrrrrrrrrrrrrrrrrrrpppppppppppppaaaaaaaaaaaaaaathe real text
@@ -340,7 +340,7 @@ pub fn challenge14() {
// | ^ first_block_index
// \ prefix_padding
for block_index in first_block_index..block_count {
let mut clear_text_block = vec![];
let mut cleartext_block = vec![];
for padding_length in (0..block_size).rev() {
let full_padding_text = vec![b'-'; prefix_padding_size + padding_length];
let expected = encryption_oracle(prefix, key, &Bytes(full_padding_text.to_vec()));
@@ -350,15 +350,15 @@ pub fn challenge14() {
full_padding_text.to_vec()
} else {
let mut prefix_padding = vec![b'-'; prefix_padding_size];
let clear_text_offset = ((block_index - first_block_index - 1) * block_size)
let cleartext_offset = ((block_index - first_block_index - 1) * block_size)
+ (block_size - padding_length);
prefix_padding.append(
&mut clear_text[clear_text_offset..(clear_text_offset + padding_length)]
&mut cleartext[cleartext_offset..(cleartext_offset + padding_length)]
.to_vec(),
);
prefix_padding
};
known_text.append(&mut clear_text_block.to_vec());
known_text.append(&mut cleartext_block.to_vec());
for i in 0..255 {
let mut guess_text = known_text.to_vec();
@@ -366,15 +366,15 @@ pub fn challenge14() {
let cipher_block = encryption_oracle(prefix, key, &Bytes(guess_text))
.get_block(first_block_index, block_size);
if cipher_block.0 == expected_block.0 {
clear_text_block.push(i);
cleartext_block.push(i);
break;
}
}
}
clear_text.append(&mut clear_text_block);
cleartext.append(&mut cleartext_block);
}
// We get last byte from cbs padding so remove it.
Bytes(clear_text[0..(clear_text.len() - 1)].to_vec())
Bytes(cleartext[0..(cleartext.len() - 1)].to_vec())
}
let prefix = Bytes::random_range(0, 200);
@@ -383,8 +383,8 @@ pub fn challenge14() {
let prefix_len = get_prefix_size(&prefix, &key);
assert_eq!(prefix.len(), prefix_len);
let roundtrip_text = decode(&prefix, &key);
let clear_text = read("data/12.txt");
assert_eq!(roundtrip_text, clear_text);
let cleartext = read("data/12.txt");
assert_eq!(roundtrip_text, cleartext);
println!(
"[okay] Challenge 14: {}",
roundtrip_text.to_utf8()[..17].to_string()