Finish implementation of Bleichenbacher's e=3 RSA Attack finally

This commit is contained in:
2022-12-10 21:04:30 -05:00
parent 35f5137518
commit 6133d17f92
3 changed files with 50 additions and 41 deletions

View File

@@ -210,46 +210,45 @@ pub fn rsa_decrypt_str(c: &BigNum, p: &RsaPrivateKey) -> Result<String, ErrorSta
Ok(String::from(std::str::from_utf8(&m.to_vec()).unwrap()))
}
pub fn rsa_sign(m: &str, p: &RsaPublicKey) -> Result<BigNum, ErrorStack> {
pub fn rsa_sign(m: &str, p: &RsaPrivateKey) -> Result<BigNum, ErrorStack> {
let hash = sha256(m.as_bytes());
let m = BigNum::from_slice(&hash)?;
rsa_encrypt(&m, p)
let m = rsa_padding_add_pkcs1(&m, p.n.num_bytes())?;
rsa_decrypt_unpadded(&m, p)
}
pub fn rsa_verify(m: &str, p: &RsaPrivateKey, signature: &BigNum) -> Result<bool, ErrorStack> {
pub fn rsa_verify(m: &str, p: &RsaPublicKey, signature: &BigNum) -> Result<bool, ErrorStack> {
let hash = BigNum::from_slice(&sha256(m.as_bytes()))?;
let m = rsa_decrypt(signature, p)?;
let m = rsa_encrypt_unpadded(signature, p)?;
let m = rsa_padding_remove_pkcs1(&m, p.n.num_bytes())?;
Ok(m == hash)
}
pub fn rsa_verify_insecure(
m: &str,
p: &RsaPrivateKey,
p: &RsaPublicKey,
signature: &BigNum,
) -> Result<bool, ErrorStack> {
let hash = BigNum::from_slice(&sha256(m.as_bytes()))?;
const SHA256_HASH_LEN: usize = 32;
let pad_to = p.n.num_bytes();
let m = rsa_decrypt_unpadded(signature, p)?;
println!("{:?}", m.to_vec());
let m = rsa_encrypt_unpadded(signature, p)?;
assert!(m.num_bytes() + 1 == pad_to, "Padding length incorrect");
// There was, 7 years ago, a common implementation flaw with RSA verifiers: they'd verify
// signatures by "decrypting" them (cubing them modulo the public exponent) and then "parsing"
// them by looking for 00h 01h ... ffh 00h ASN.1 HASH.
let v = m.to_vec_padded(pad_to)?;
println!("{:?}", v);
let pad_to: usize = pad_to.try_into().unwrap();
assert!(v[0] == 0, "PKCS1 padding incorrect");
assert!(v[1] == 1, "PKCS1 padding incorrect");
assert!(
v[pad_to - SHA256_HASH_LEN - 2] == 0xff,
"PKCS1 padding incorrect"
);
assert!(
v[pad_to - SHA256_HASH_LEN - 1] == 0,
"PKCS1 padding incorrect"
);
let sig = BigNum::from_slice(&v[pad_to - SHA256_HASH_LEN..])?;
let mut i = 2;
while i < v.len() - 1 {
if v[i] == 0xff && v[i + 1] == 0x0 {
break;
}
i += 1;
}
i += 2;
let sig = BigNum::from_slice(&v[i..i + SHA256_HASH_LEN])?;
Ok(sig == hash)
}