Finish challenge 25 and update License
This commit is contained in:
44
src/set4.rs
44
src/set4.rs
@@ -1,9 +1,47 @@
|
||||
use crate::{bytes::Bytes, utils};
|
||||
use crate::{bytes::Bytes, ctr, utils};
|
||||
|
||||
pub fn challenge25() {
|
||||
let cipher = utils::read_base64("data/25.txt");
|
||||
let key = Bytes::from_utf8("YELLOW SUBMARINE");
|
||||
let _cleartext = crate::ecb::decrypt(&key, &cipher);
|
||||
let plaintext = crate::ecb::decrypt(&key, &cipher);
|
||||
|
||||
println!("[xxxx] Challenge 25: wip");
|
||||
let key = Bytes::random(16);
|
||||
let nonce: u64 = 0; // otherwise edit would require the nonce too?
|
||||
|
||||
// Now, write the code that allows you to "seek" into the ciphertext,
|
||||
// decrypt, and re-encrypt with different plaintext. Expose this as a
|
||||
// function, like, "edit(ciphertext, key, offset, newtext)".
|
||||
fn edit(ciphertext: &Bytes, key: &Bytes, offset: usize, newtext: &Vec<u8>) -> Bytes {
|
||||
let mut plaintext = ctr::decrypt(key, 0, ciphertext);
|
||||
if offset + newtext.len() > plaintext.len() {
|
||||
panic!("challenge25 - edit - out of bounds");
|
||||
}
|
||||
|
||||
for i in 0..newtext.len() {
|
||||
plaintext.0[offset + i] = newtext[i];
|
||||
}
|
||||
ctr::encrypt(key, 0, &plaintext)
|
||||
}
|
||||
|
||||
// Imagine the "edit" function was exposed to attackers by means of an API
|
||||
// call that didn't reveal the key or the original plaintext; the attacker
|
||||
// has the ciphertext and controls the offset and "new text". Recover the
|
||||
// original plaintext.
|
||||
let ciphertext = ctr::encrypt(&key, nonce, &plaintext);
|
||||
let newtext = vec![b'a'; ciphertext.len()];
|
||||
let cipher_newtext = edit(&ciphertext, &key, 0, &newtext);
|
||||
let keystream = crate::utils::xor(&newtext, &cipher_newtext.0);
|
||||
let recovered_plaintext = Bytes(crate::utils::xor(&keystream, &ciphertext.0));
|
||||
assert_eq!(plaintext, recovered_plaintext);
|
||||
|
||||
println!("[okay] Challenge 25: recovered AES CTR plaintext via edit");
|
||||
|
||||
// A folkloric supposed benefit of CTR mode is the ability to easily "seek
|
||||
// forward" into the ciphertext; to access byte N of the ciphertext, all you
|
||||
// need to be able to do is generate byte N of the keystream. Imagine if
|
||||
// you'd relied on that advice to, say, encrypt a disk.
|
||||
}
|
||||
|
||||
pub fn challenge26() {
|
||||
println!("[xxxx] Challenge 26: TBD");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user