此刻,我正在尝试使用普通RSA来理解数学。在使用this盲目解密代码而不是仅使用m**d%n
的直接方法时,我遇到了一个问题,这种方法工作得很好。
现在的问题是,对于大数(4096)位质数,我的代码可以正常工作,但是对于小数,我具有最大的随机数(r)。
对于p = 67和q = 97,此最大值为r = 542。
代码:
from functools import reduce
from secrets import SystemRandom
class RsaKeyPair(object):
def __init__(self, p=None, q=None, e=None, n=None, d=None, keylength=4096):
self.sec = SystemRandom()
if keylength < 1024:
raise ValueError("For security reasons keylength has to be at least 1024")
if p: self.p = p
else: self.p = generate_prime_number(length=keylength//2)
if q: self.q = q
else: self.q = generate_prime_number(length=keylength//2)
self.phi = (self.p - 1) * (self.q - 1)
if e: self.e = e
else: self.e = self.get_e()
if n: self.n = n
else: self.n = p * q
if d: self.d = d
else: self.d = self.get_d()
self.quick_test()
def quick_test(self):
if (self.e*self.d)%self.phi != 1:
raise ValueError("e, d and phi value don`t match. Have you used custom ones?")
msg = 12
cipher = self.encrypt(msg)
if self.decrypt(cipher) != msg:
raise ValueError("Some values dont work out. Have you used custom ones?")
def encrypt(self, msg):
return pow(msg, self.e, self.n)
def decrypt(self, cipher):
r = 542#Raises error if bigger
s = pow(r, self.e, self.n)
X = (cipher*s)%self.n
Y = pow(X, self.d, self.n)
return (Y//r)%self.n
def factors(n):
return set(reduce(list.__add__, ([i, n//i] for i in range(1, int(pow(n, 0.5) + 1)) if n % i == 0)))
def get_e(self):
for i in range(3,10001,2):
d = self.factors(i)
d.discard(1)
for j in d:
if self.phi % j == 0:
break
else:
return i
def get_d(self):
t1 = [self.phi, self.e]
t2 = [self.phi, 1]
while t1[1] != 1:
tb1 = t1[0] // t1[1]
tb2 = tb1 * t1[1]
tb3 = tb1 * t2[1]
td1 = t1[0] - tb2
td2 = t2[0] - tb3
if td2 < 0:
td2 += self.phi
t1 = [t1[1], td1]
t2 = [t2[1], td2]
return t2[1]
def is_prime(n, k=128):
if n == 2 or n == 3:
return True
if n <= 1 or n % 2 == 0:
return False
s = 0
r = n - 1
while r & 1 == 0:
s += 1
r //= 2
for _ in range(k):
a = randrange(2, n - 1)
x = pow(a, r, n)
if x != 1 and x != n - 1:
j = 1
while j < s and x != n - 1:
x = pow(x, 2, n)
if x == 1:
return False
j += 1
if x != n - 1:
return False
return True
def generate_prime_candidate(length):
p = getrandbits(length)
p |= (1 << length - 1) | 1
return p
def generate_prime_number(length=2048):
p = 4
while not is_prime(p, 128):
p = generate_prime_candidate(length)
return p
def ppp(self):
return [self.p, self.q, self.e, self.phi, self.n, self.d]
test = RsaKeyPair(p=67, q=97, e=5, d=5069)
print(test.ppp())
该错误位于解密函数中,因为它返回一个错误值0。这是带有自定义错误的出口:
Traceback (most recent call last):
File "main.py", line 115, in <module>
test = RsaKeyPair(p=67, q=97, e=5, d=5069)
File "main.py", line 24, in __init__
self.quick_test()
File "main.py", line 32, in quick_test
raise ValueError("Some values dont work out. Have you used custom ones?")
ValueError: Some values dont work out. Have you used custom ones?