mirror of
https://github.com/20kaushik02/CSE548_ACNS_Work.git
synced 2025-12-06 06:24:07 +00:00
project: rsa close primes
completed
This commit is contained in:
parent
4ce1b6611a
commit
e6950f50f9
9
Project/README.md
Normal file
9
Project/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Weak primes in RSA private key - Fermat's factorization method
|
||||||
|
|
||||||
|
- The RSA modulus is constructed from two "random" prime numbers
|
||||||
|
- For the special case where the primes are close, [Fermat's factorization method](https://eprint.iacr.org/2023/026.pdf) can be applied to factor the modulus with ease
|
||||||
|
- However, for a 2048-bit key, this works only if the first approx. 500 bits of the prime factors are identical
|
||||||
|
- The probability of this happening on a properly implemented random prime generator is approx. 1 in 2<sup>500</sup>
|
||||||
|
- Only feasible if the above constraint is satisfied, else computationally expensive(infeasible?)
|
||||||
|
- References:
|
||||||
|
- Hanno B¨ock. 2023. Fermat Factorization in the Wild. *Cryptology ePrint Archive, Paper 2023/026* - https://eprint.iacr.org/2023/026.pdf
|
||||||
74
Project/rsa_weak_prime.py
Normal file
74
Project/rsa_weak_prime.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import math
|
||||||
|
import time
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
from Crypto.Cipher import PKCS1_OAEP
|
||||||
|
|
||||||
|
|
||||||
|
# Fermat's factorization
|
||||||
|
def fermat(n, start):
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
# if primes are close, mean of primes is close to sqrt(n)
|
||||||
|
a = math.isqrt(n) + 1
|
||||||
|
b = math.isqrt((a * a) - n)
|
||||||
|
|
||||||
|
# check b^2 = a^2 - n
|
||||||
|
while (b * b) != ((a * a) - n):
|
||||||
|
# print("[+] bit length of (a2 - n):", int(((a*a) -n)).bit_length())
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
a += 1
|
||||||
|
b = math.isqrt((a * a) - n)
|
||||||
|
|
||||||
|
if count % 1e8 == 0:
|
||||||
|
print("time elapsed:", time.perf_counter() - start, "seconds", flush=True)
|
||||||
|
|
||||||
|
# calc the primes from their mean and distance
|
||||||
|
p = a + b
|
||||||
|
q = a - b
|
||||||
|
return p, q, count
|
||||||
|
|
||||||
|
|
||||||
|
pub_key = RSA.import_key(open("key.pub", "r").read())
|
||||||
|
|
||||||
|
# testing
|
||||||
|
# computerphile example, intentionally weak, runs in 12 iterations
|
||||||
|
n = 5261933844650100908430030083398098838688018147149529533465444719385566864605781576487305356717074882505882701585297765789323726258356035692769897420620858774763694117634408028918270394852404169072671551096321238430993811080749636806153881798472848720411673994908247486124703888115308603904735959457057925225503197625820670522050494196703154086316062123787934777520599894745147260327060174336101658295022275013051816321617046927321006322752178354002696596328204277122466231388232487691224076847557856202947748540263791767128195927179588238799470987669558119422552470505956858217654904628177286026365989987106877656917
|
||||||
|
e = 65537
|
||||||
|
|
||||||
|
# example posted in canvas discussions
|
||||||
|
# seems to be safe from this method
|
||||||
|
# n = 125992118149870746006493654389175279527472408386640156684228205007899250636526783672946765874704581329243206029282525787037543662260258606135966229683550046557542867359322036785322426006162242420991369663470231974481363297634340923634481349310535206763098422642504687457452847274657348442529853593836012279453
|
||||||
|
# e = 65537
|
||||||
|
|
||||||
|
# example in citizenlab report
|
||||||
|
# n = 245406417573740884710047745869965023463
|
||||||
|
# e = 65537
|
||||||
|
|
||||||
|
pub_key = RSA.construct((n, e))
|
||||||
|
|
||||||
|
start = time.perf_counter()
|
||||||
|
d_p, d_q, iters = fermat(pub_key.n, start)
|
||||||
|
end = time.perf_counter()
|
||||||
|
|
||||||
|
print("found solution in {} seconds ({} iterations)".format(end - start, iters))
|
||||||
|
print("prime factors are:\n\np:", d_p, "\nq:", d_q)
|
||||||
|
print("\nn == p * q:", pub_key.n == d_p * d_q)
|
||||||
|
|
||||||
|
phi_n = (d_p - 1) * (d_q - 1)
|
||||||
|
d = pow(pub_key.e, -1, phi_n)
|
||||||
|
|
||||||
|
print("\nprivate key exponent d =", d)
|
||||||
|
priv_key = RSA.construct((pub_key.n, pub_key.e, d), consistency_check=True)
|
||||||
|
|
||||||
|
print("verifying...")
|
||||||
|
enc_key = PKCS1_OAEP.new(pub_key)
|
||||||
|
cipher_text = enc_key.encrypt("hello world".encode())
|
||||||
|
|
||||||
|
dec_key = PKCS1_OAEP.new(priv_key)
|
||||||
|
plain_text = dec_key.decrypt(cipher_text).decode()
|
||||||
|
|
||||||
|
if plain_text == "hello world":
|
||||||
|
print("cracked! saving key...")
|
||||||
|
with open("cracked.key", "w") as f:
|
||||||
|
print(priv_key.export_key().decode(), file=f)
|
||||||
Loading…
x
Reference in New Issue
Block a user