Implement assignment 36.
parent
49d590ea44
commit
7a9225ccb0
|
@ -63,4 +63,5 @@ fn main() {
|
||||||
set5::challenge34();
|
set5::challenge34();
|
||||||
set5::challenge35();
|
set5::challenge35();
|
||||||
set5::challenge36();
|
set5::challenge36();
|
||||||
|
set5::challenge37();
|
||||||
}
|
}
|
||||||
|
|
94
src/set5.rs
94
src/set5.rs
|
@ -1,6 +1,9 @@
|
||||||
use crate::bytes::Bytes;
|
use crate::bytes::Bytes;
|
||||||
use crate::rsa;
|
use crate::rsa;
|
||||||
|
use crate::sha1;
|
||||||
|
use crate::sha1::Sha1;
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
|
use num_bigint::RandBigInt;
|
||||||
use num_bigint::ToBigUint;
|
use num_bigint::ToBigUint;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
|
@ -97,8 +100,8 @@ mod challenge34 {
|
||||||
pub fn new(p: BigUint, g: &BigUint) -> Self {
|
pub fn new(p: BigUint, g: &BigUint) -> Self {
|
||||||
let keypair = rsa::Keypair::make(&p, g);
|
let keypair = rsa::Keypair::make(&p, g);
|
||||||
Bot {
|
Bot {
|
||||||
p: p,
|
p,
|
||||||
keypair: keypair,
|
keypair,
|
||||||
s: None,
|
s: None,
|
||||||
key: None,
|
key: None,
|
||||||
}
|
}
|
||||||
|
@ -315,5 +318,90 @@ pub fn challenge35() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn challenge36() {
|
pub fn challenge36() {
|
||||||
println!("[xxxx] Challenge 36: xxxx");
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
// C & S
|
||||||
|
// Agree on N=[NIST Prime], g=2, k=3, I (email), P (password)
|
||||||
|
let n = challenge33::load_large_prime();
|
||||||
|
let g = 2_u8.to_biguint().unwrap();
|
||||||
|
let k = 3_u8.to_biguint().unwrap();
|
||||||
|
let _i = Bytes::from_utf8("john1337@wayne.com");
|
||||||
|
let p = Bytes::from_utf8("horse planet carpet country");
|
||||||
|
|
||||||
|
|
||||||
|
// We will use SHA1 instead of SHA256 for the whole exercise because I am lazy.
|
||||||
|
|
||||||
|
// S
|
||||||
|
// Generate salt as random integer
|
||||||
|
// Generate string xH=SHA256(salt|password)
|
||||||
|
// Convert xH to integer x somehow (put 0x on hexdigest)
|
||||||
|
// Generate v=g**x % N
|
||||||
|
// Save everything but x, xH
|
||||||
|
let salt: u32 = rng.gen();
|
||||||
|
let mut salt_password = salt.to_be_bytes().to_vec();
|
||||||
|
salt_password.append(&mut p.0.clone());
|
||||||
|
let mut sha1 = Sha1::default();
|
||||||
|
let xh = sha1.hash(&Bytes(salt_password));
|
||||||
|
let x = BigUint::from_bytes_be(xh.0[0..4].try_into().unwrap());
|
||||||
|
let v = g.modpow(&x, &n);
|
||||||
|
std::mem::drop(xh);
|
||||||
|
std::mem::drop(x);
|
||||||
|
std::mem::drop(sha1);
|
||||||
|
|
||||||
|
// C->S
|
||||||
|
// Send I, A=g**a % N (a la Diffie Hellman)
|
||||||
|
let a = rng.gen_biguint_below(&n);
|
||||||
|
let a_public = g.modpow(&a, &n);
|
||||||
|
|
||||||
|
// S->C
|
||||||
|
// Send salt, B=kv + g**b % N
|
||||||
|
let b = rng.gen_biguint_below(&n);
|
||||||
|
let b_public = k.clone() * v.clone() + g.modpow(&b, &n);
|
||||||
|
|
||||||
|
// S, C
|
||||||
|
// Compute string uH = SHA256(A|B), u = integer of uH
|
||||||
|
let mut a_b = a_public.to_bytes_be();
|
||||||
|
a_b.append(&mut b_public.to_bytes_be());
|
||||||
|
let mut sha1 = Sha1::default();
|
||||||
|
let uh = sha1.hash(&Bytes(a_b));
|
||||||
|
let u = BigUint::from_bytes_be(uh.0[0..4].try_into().unwrap());
|
||||||
|
|
||||||
|
// C
|
||||||
|
// Generate string xH=SHA256(salt|password)
|
||||||
|
// Convert xH to integer x somehow (put 0x on hexdigest)
|
||||||
|
// Generate S = (B - k * g**x)**(a + u * x) % N
|
||||||
|
// Generate K = SHA256(S)
|
||||||
|
let mut salt_password = salt.to_be_bytes().to_vec();
|
||||||
|
salt_password.append(&mut p.0.clone());
|
||||||
|
let mut sha1 = Sha1::default();
|
||||||
|
let xh = sha1.hash(&Bytes(salt_password));
|
||||||
|
let x = BigUint::from_bytes_be(xh.0[0..4].try_into().unwrap());
|
||||||
|
let s = (b_public - k * g.modpow(&x, &n)).modpow(&(a + &u * x), &n);
|
||||||
|
let mut sha1 = Sha1::default();
|
||||||
|
let k_client = sha1.hash(&Bytes(s.to_bytes_be()));
|
||||||
|
|
||||||
|
// S
|
||||||
|
// Generate S = (A * v**u) ** b % N
|
||||||
|
// Generate K = SHA256(S)
|
||||||
|
let s = (a_public * v.modpow(&u, &n)).modpow(&b, &n);
|
||||||
|
let mut sha1 = Sha1::default();
|
||||||
|
let k_server = sha1.hash(&Bytes(s.to_bytes_be()));
|
||||||
|
|
||||||
|
assert_eq!(k_client, k_server);
|
||||||
|
|
||||||
|
// C->S
|
||||||
|
// Send HMAC-SHA256(K, salt)
|
||||||
|
let salt = Bytes(salt.to_be_bytes().to_vec());
|
||||||
|
let mac_server = sha1::hmac_sha1(&k_server, &salt);
|
||||||
|
|
||||||
|
// S->C
|
||||||
|
// Send "OK" if HMAC-SHA256(K, salt) validates
|
||||||
|
let mac_client = sha1::hmac_sha1(&k_server, &salt);
|
||||||
|
assert_eq!(mac_server, mac_client, "HMAC verification failed");
|
||||||
|
|
||||||
|
println!("[okay] Challenge 36: implement secure remote password");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn challenge37() {
|
||||||
|
println!("[xxxx] Challenge 37: TBD");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue