def privatekey_check(N, p, q, d, e): ret = False txt = "" nlen = getpubkeysz(N) if is_prime(p) == False: ret = True txt += "p IS NOT PROBABLE PRIME\n" if is_prime(q) == False: txt = "q IS NOT PROBABLE PRIME\n" if gcd(p, e) > 1: ret = True txt = "p and e ARE NOT RELATIVELY PRIME\n" if gcd(q, e) > 1: ret = True txt += "q and e ARE NOT RELATIVELY PRIME\n" if p * q != N: ret = True txt += "n IS NOT p * q\n" if not (abs(p - q) > (2**((nlen >> 1) - 100))): ret = True txt += "|p - q| IS NOT > 2^(nlen/2 - 100)\n" if not (p > 2**((nlen >> 1) - 1)): ret = True txt += "p IS NOT > 2^(nlen/2 - 1)\n" if not (q > 2**((nlen >> 1) - 1)): ret = True txt += "q IS NOT > 2^(nlen/2 - 1)\n" if not (d > 2**(nlen >> 1)): ret = True txt += "d IS NOT > 2^(nlen/2)\n" if not (d < lcm(p - 1, q - 1)): ret = True txt += "d IS NOT < lcm(p-1,q-1)\n" unc = (gcd(e - 1, p - 1) + 1) * (gcd(e - 1, q - 1) + 1) if unc > 9: ret = True txt += "The number of unconcealed messages is %d > min\n" % unc try: inv = invert(e, lcm(p - 1, q - 1)) except: inv = None ret = True txt += "e IS NOT INVERTIBLE mod lcm(p-1,q-1)\n" if d != inv: ret = True txt += "d IS NOT e^(-1) mod lcm(p-1,q-1)" return (ret, txt)
def attack(self, publickey, cipher=[], progress=True): """use elliptic curve method only works if the sageworks() function returned True """ try: sageresult = [] try: sageresult = subprocess.check_output( ["sage", "%s/sage/ecm2.sage" % rootpath, str(publickey.n)], timeout=self.timeout, stderr=subprocess.DEVNULL, ) sageresult = sageresult[1:-2].split(b", ") except (subprocess.CalledProcessError, subprocess.TimeoutExpired): return (None, None) if len(sageresult) > 0: plain = [] sageresults = [int(_.decode("utf-8")) for _ in sageresult] phi = 1 for fac in sageresults: phi = phi * (int(fac) - 1) if cipher is not None and len(cipher) > 0: for c in cipher: try: cipher_int = int.from_bytes(c, "big") d = invert(publickey.e, phi) m = hex(powmod(cipher_int, d, publickey.n))[2::] plain.append(bytes.fromhex(m)) except: continue return (None, plain) return (None, None) except KeyboardInterrupt: pass return (None, None)
def __init__( self, p=None, q=None, e=None, n=None, d=None, filename=None, password=None, ): """Create private key from base components :param p: extracted from n :param q: extracted from n :param e: exponent :param n: n from public key """ self.p = None if p is not None: self.p = p self.q = None if q is not None: self.q = q self.e = None if e is not None: self.e = e self.n = None if n is not None: self.n = n self.phi = None if self.p is not None and self.q is not None and self.phi is None: if self.p != self.q: self.phi = (self.p - 1) * (self.q - 1) else: self.phi = (self.p**2) - self.p self.d = None if self.phi is not None and self.e is not None: try: self.d = int(invert(e, self.phi)) except ValueError: # invmod failure logger.error("[!] e^d==1 inversion error, check your math.") pass self.key = None if self.p is not None and self.q is not None and self.d is not None: self.key = RSA.construct((self.n, self.e, self.d, self.p, self.q)) elif n is not None and e is not None and d is not None: try: self.key = RSA.construct((self.n, self.e, self.d)) except NotImplementedError: pass elif filename is not None: with open(filename, "rb") as key_data_fd: self.key = serialization.load_pem_private_key( key_data_fd.read(), password=password, backend=default_backend()) private_numbers = self.key.private_numbers() if p is None: self.p = private_numbers.p if q is None: self.q = private_numbers.q if d is None: self.d = private_numbers.d if self.p and self.q: self.n = self.p * self.q if self.phi is None: if self.p != self.q: self.phi = (self.p - 1) * (self.q - 1) else: self.phi = (self.p**2) - self.p