Python普通RSA解密仅使特定值盲目

时间:2018-07-03 09:35:37

标签: python python-3.x cryptography rsa

此刻,我正在尝试使用普通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?

0 个答案:

没有答案