Esempio n. 1
0
 def attack(self, publickey, cipher=[], progress=True):
     """
     Pisano(mersenne) period factorization algorithm optimal for keys sub 70 bits in less than a minute.
     The attack is very similar to londahl's
     """
     Fib = Fibonacci(progress=progress)
     with timeout(self.timeout):
         try:
             B1, B2 = (
                 pow(10, (ilog10(publickey.n) // 2) - 4),
                 0,
             )  # Arbitrary selected bounds, biger b2 is more faster but more failed factorizations.
             try:
                 r = Fib.factorization(publickey.n, B1, B2)
             except OverflowError:
                 r = None
             if r is not None:
                 publickey.p, publickey.q = r
                 priv_key = PrivateKey(
                     int(publickey.p),
                     int(publickey.q),
                     int(publickey.e),
                     int(publickey.n),
                 )
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
     return (None, None)
Esempio n. 2
0
    def attack(self, publickey, cipher=[], progress=True):
        """Run attack with Euler method"""
        if not hasattr(publickey, "p"):
            publickey.p = None
        if not hasattr(publickey, "q"):
            publickey.q = None

        # Euler attack
        with timeout(self.timeout):
            try:
                try:
                    if (publickey.n - 1) % 4 == 0:
                        euler_res = self.euler(publickey.n)
                    else:
                        self.logger.error(
                            "[!] Public key modulus must be congruent 1 mod 4 to work with euler method."
                        )
                        return (None, None)
                except:
                    return (None, None)
                if euler_res and len(euler_res) > 1:
                    publickey.p, publickey.q = euler_res

                if publickey.q is not None:
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
            except TimeoutError:
                return (None, None)

        return (None, None)
Esempio n. 3
0
    def attack(self, publickey, cipher=[], progress=True):
        """Run fermat attack with a timeout"""
        try:
            with timeout(seconds=self.timeout):
                try:
                    publickey.p, publickey.q = self.fermat(publickey.n)
                except TimeoutError:
                    return (None, None)

        except FactorizationError:
            return (None, None)

        if publickey.p is not None and publickey.q is not None:
            try:
                priv_key = PrivateKey(
                    n=publickey.n,
                    p=int(publickey.p),
                    q=int(publickey.q),
                    e=int(publickey.e),
                )
                return (priv_key, None)
            except ValueError:
                return (None, None)

        return (None, None)
Esempio n. 4
0
    def attack(self, publickey, cipher=[], progress=True):
        """Run dixon attack with a timeout"""
        try:
            with timeout(seconds=self.timeout):
                try:
                    if publickey.n <= 10**10:
                        publickey.p, publickey.q = dixon_factor(publickey.n)
                    else:
                        self.logger.info(
                            "[-] Dixon is too slow for pubkeys > 10^10...")
                        return (None, None)
                except TimeoutError:
                    return (None, None)

        except FactorizationError:
            return (None, None)

        if publickey.p is not None and publickey.q is not None:
            try:
                priv_key = PrivateKey(
                    n=publickey.n,
                    p=int(publickey.p),
                    q=int(publickey.q),
                    e=int(publickey.e),
                )
                return (priv_key, None)
            except ValueError:
                return (None, None)

        return (None, None)
Esempio n. 5
0
    def attack(self, publickey, cipher=[], progress=True):
        """Run attack with Pollard P1"""
        if not hasattr(publickey, "p"):
            publickey.p = None
        if not hasattr(publickey, "q"):
            publickey.q = None

        with timeout(self.timeout):
            try:
                # Pollard P-1 attack
                try:
                    poll_res = self.pollard_P_1(publickey.n, progress)
                except RecursionError:
                    return (None, None)
                if poll_res and len(poll_res) > 1:
                    publickey.p, publickey.q = poll_res

                if publickey.q is not None:
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
            except TimeoutError:
                return (None, None)
        return (None, None)
Esempio n. 6
0
    def attack(self, publickey, cipher=[], progress=True):
        """Qi Cheng - A New Class of Unsafe Primes"""
        try:
            sageresult = int(
                subprocess.check_output(
                    [
                        "sage",
                        "%s/sage/qicheng.sage" % rootpath,
                        str(publickey.n)
                    ],
                    timeout=self.timeout,
                    stderr=subprocess.DEVNULL,
                ))
        except (subprocess.CalledProcessError, subprocess.TimeoutExpired,
                ValueError):
            return (None, None)

        if sageresult > 0:
            p = sageresult
            q = publickey.n // sageresult
            priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                  int(publickey.n))
            return (priv_key, None)
        else:
            return (None, None)
Esempio n. 7
0
    def attack(self, publickey, cipher=[], progress=True):
        """binary polinomial factoring"""
        try:
            sageresult = str(
                subprocess.check_output(
                    [
                        "sage",
                        "%s/sage/binary_polinomial_factoring.sage" % rootpath,
                        str(publickey.n),
                    ],
                    timeout=self.timeout,
                    stderr=subprocess.DEVNULL,
                )).split(" ")

        except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
            return (None, None)

        try:
            p = int(sageresult[0])
        except ValueError:
            return (None, None)

        if p > 0:
            q = publickey.n // p
            priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                  int(publickey.n))
            return (priv_key, None)
        else:
            return (None, None)
Esempio n. 8
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against primorial +-1 composites"""
     with timeout(self.timeout):
         try:
             limit = 10000
             prime = 1
             primorial = 1
             p = q = None
             for x in tqdm(range(0, limit), disable=(not progress)):
                 prime = next_prime(prime)
                 primorial *= prime
                 primorial_p1 = [primorial - 1, primorial + 1]
                 g0, g1 = gcd(primorial_p1[0],
                              publickey.n), gcd(primorial_p1[1],
                                                publickey.n)
                 if 1 < g0 < publickey.n:
                     p = publickey.n // g0
                     q = g0
                     break
                 if 1 < g1 < publickey.n:
                     p = publickey.n // g1
                     q = g1
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 9
0
 def attack(self, publickey, cipher=[], progress=True):
     """Factor n if mininum of crt exponent is small enough"""
     try:
         p = int(
             subprocess.check_output(
                 [
                     "sage",
                     "%s/sage/small_crt_exp.sage" % rootpath,
                     str(publickey.n),
                     str(publickey.e),
                     str(1 << 32),  # Default upper bound of min(d_p, d_q)
                 ],
                 timeout=self.timeout,
                 stderr=subprocess.DEVNULL,
             ))
     except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
         return (None, None)
     if p > 0:
         q = publickey.n // p
         privatekey = PrivateKey(
             p=p,
             q=q,
             e=publickey.e,
             n=publickey.n,
         )
         return (privatekey, None)
     return (None, None)
Esempio n. 10
0
 def attack(self, publickey, cipher=[], progress=True):
     """Use boneh durfee method, should return a d value, else returns 0
     only works if the sageworks() function returned True
     many of these problems will be solved by the wiener attack module but perhaps some will fall through to here
     """
     try:
         sageresult = int(
             subprocess.check_output(
                 [
                     "sage",
                     "%s/sage/boneh_durfee.sage" % rootpath,
                     str(publickey.n),
                     str(publickey.e),
                 ],
                 timeout=self.timeout,
                 stderr=subprocess.DEVNULL,
             ))
     except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
         return (None, None)
     if sageresult > 0:
         tmp_priv = RSA.construct(
             (int(publickey.n), int(publickey.e), int(sageresult)), )
         publickey.p = tmp_priv.p
         publickey.q = tmp_priv.q
         privatekey = PrivateKey(
             p=int(publickey.p),
             q=int(publickey.q),
             e=int(publickey.e),
             n=int(publickey.n),
         )
         return (privatekey, None)
     return (None, None)
Esempio n. 11
0
    def attack(self, publickey, cipher=[], progress=True):
        if is_roca_vulnerable(publickey.n):
            try:
                sageresult = subprocess.check_output(
                    [
                        "sage",
                        "%s/sage/roca_attack.py" % rootpath,
                        str(publickey.n)
                    ],
                    timeout=self.timeout,
                    stderr=subprocess.DEVNULL,
                )

            except (subprocess.CalledProcessError,
                    subprocess.TimeoutExpired) as e:
                return (None, None)

            if b"FAIL" not in sageresult and b":" in sageresult:
                sageresult = sageresult.decode("utf-8").strip()
                p, q = map(int, sageresult.split(":"))
                priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                      int(publickey.n))
                return (priv_key, None)
            else:
                return (None, None)
        else:
            self.logger.info("[-] This key is not roca, skiping test...")
            return (None, None)
Esempio n. 12
0
    def attack(self, publickey, cipher=[], progress=True):
        """Try to factorize using yafu"""
        with timeout(self.timeout):
            try:
                if publickey.n.bit_length() > 1024:
                    self.logger.error(
                        "[!] Warning: Modulus too large for SIQS attack module"
                    )
                    return (None, None)

                siqsobj = SiqsAttack(publickey.n, self.timeout)

                if siqsobj.testyafu():
                    siqsobj.doattack()
                else:
                    return (None, None)

                if siqsobj.p and siqsobj.q:
                    publickey.q = siqsobj.q
                    publickey.p = siqsobj.p
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
            except TimeoutError:
                return (None, None)
        return (None, None)
Esempio n. 13
0
 def attack(self, publickey, cipher=[], progress=True):
     """Code/idea from Renaud Lifchitz's talk 15 ways to break RSA security @ OPCDE17
     only works if the sageworks() function returned True
     """
     try:
         r = subprocess.check_output(
             [
                 "sage",
                 "%s/sage/smallfraction.sage" % rootpath,
                 str(publickey.n)
             ],
             timeout=self.timeout,
             stderr=subprocess.DEVNULL,
         )
         sageresult = int(r)
         if sageresult > 0:
             publickey.p = sageresult
             publickey.q = publickey.n // publickey.p
             priv_key = PrivateKey(
                 int(publickey.p),
                 int(publickey.q),
                 int(publickey.e),
                 int(publickey.n),
             )
             return (priv_key, None)
     except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
         return (None, None)
     return (None, None)
Esempio n. 14
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against mersenne composites"""
     with timeout(self.timeout):
         try:
             p = q = None
             for i in tqdm(range(2, ilog2(publickey.n)),
                           disable=(not progress)):
                 i2 = 2**i
                 mersenne = [i2 - 1, i2 + 1]
                 g0, g1 = gcd(mersenne[0],
                              publickey.n), gcd(mersenne[1], publickey.n)
                 if 1 < g0 < publickey.n:
                     p = publickey.n // g0
                     q = g0
                     break
                 if 1 < g1 < publickey.n:
                     p = publickey.n // g1
                     q = g1
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 15
0
    def attack(self, publickey, cipher=[], progress=True):
        """Run attack with Pollard Rho"""
        if not hasattr(publickey, "p"):
            publickey.p = None
        if not hasattr(publickey, "q"):
            publickey.q = None

        # pollard Rho attack

        with timeout(self.timeout):
            try:
                try:
                    poll_res = self.pollard_rho(publickey.n)
                except RecursionError:
                    print("RecursionError")
                    return (None, None)

                if poll_res != None:
                    publickey.p = poll_res
                    publickey.q = publickey.n // publickey.p

                if publickey.q is not None:
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
            except TimeoutError:
                return (None, None)
            except TypeError:
                return (None, None)

        return (None, None)
Esempio n. 16
0
 def attack(self, publickey, cipher=[], progress=True):
     if is_roca_vulnerable(publickey.n):
         if getpubkeysz(publickey.n) <= 512:
             necaresult = subprocess.check_output(
                 ["neca", "%s" % publickey.n],
                 timeout=self.timeout,
                 stderr=subprocess.DEVNULL,
             )
             necaresult_l = necaresult.decode("utf8").split("\n")
             if b"FAIL" not in necaresult and b"*" in necaresult:
                 for line in necaresult_l:
                     r0 = line.find("N = ")
                     r1 = line.find(" * ")
                     if r0 > -1 and r1 > -1:
                         p, q = list(map(int, line.split("=")[1].split("*")))
                         priv_key = PrivateKey(
                             int(p), int(q), int(publickey.e), int(publickey.n)
                         )
                         return (priv_key, None)
             else:
                 return (None, None)
         else:
             self.logger.info(
                 "[-] This key is roca but > 512 bits, try with roca attack..."
             )
             return (None, None)
     else:
         self.logger.info("[-] This key is not roca, skiping test...")
         return (None, None)
Esempio n. 17
0
    def attack(self, publickey, cipher=[], progress=True):

        if not hasattr(publickey, "p"):
            publickey.p = None
        if not hasattr(publickey, "q"):
            publickey.q = None

        # solve with z3 theorem prover
        with timeout(self.timeout):
            try:
                try:
                    z3_res = self.z3_solve(publickey.n, self.timeout)
                except:
                    self.logger.warning("[!] z3: Internal Error.")
                    return (None, None)

                if z3_res and len(z3_res) > 1:
                    p, q = z3_res
                    publickey.p = p
                    publickey.q = q

                if publickey.q is not None:
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
                else:
                    return (None, None)
            except TimeoutError:
                return (None, None)

        return (None, None)
Esempio n. 18
0
    def attack(self, publickey, cipher=[], progress=True):
        """Factors available online?"""

        try:
            wa_enabled = True
            import wolframalpha

            app_id = os.environ.get("WA_API_KEY")
            wa_enabled = app_id != None
        except Exception:
            self.logger.warning(
                "[!] Wolfram Alpha is not enabled, install the librairies.")
            wa_enabled = False

        if not wa_enabled:
            self.logger.warning(
                "[!] Wolfram Alpha is not enabled, check if ENV WA_API_KEY is set."
            )
            self.logger.warning(
                "[!] follow: https://products.wolframalpha.com/api/documentation/"
            )
            self.logger.warning("[!] export WA_API_KEY=XXXXXX-XXXXXXXXXX")
            self.wa_client = None
            return (None, None)
        else:
            self.wa_client = wolframalpha.Client(app_id)

        with timeout(self.timeout):
            try:
                factors = self.wa_query_factors(publickey.n)
                self.logger.info("Factors: %s" % str(factors))
                if factors != None and len(factors) > 1:
                    publickey.q = factors[
                        -1]  # Let it be the last prime wich is the bigger one
                    publickey.p = publickey.n // publickey.q
                    priv_key = PrivateKey(
                        p=int(publickey.p),
                        q=int(publickey.q),
                        e=int(publickey.e),
                        n=int(publickey.n),
                    )
                    return (priv_key, None)
                else:
                    return (None, None)
            except Exception as e:
                self.logger.error(
                    "[*] wolfram alpha could not get a factorization.")
                self.logger.debug(str(e))
                return (None, None)
            except TimeoutError:
                return (None, None)
Esempio n. 19
0
    def attack(self, publickey, cipher=[], progress=True):
        """use elliptic curve method, may return a prime or may never return
        only works if the sageworks() function returned True
        """

        try:
            try:
                if self.ecmdigits is not None:
                    sageresult = int(
                        subprocess.check_output(
                            [
                                "sage",
                                "%s/sage/ecm.sage" % rootpath,
                                str(publickey.n),
                                str(self.ecmdigits),
                            ],
                            timeout=self.timeout,
                            stderr=subprocess.DEVNULL,
                        ))
                else:
                    sageresult = int(
                        subprocess.check_output(
                            [
                                "sage",
                                "%s/sage/ecm.sage" % rootpath,
                                str(publickey.n)
                            ],
                            timeout=self.timeout,
                            stderr=subprocess.DEVNULL,
                        ))
            except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
                return (None, None)

            if sageresult > 0:
                publickey.p = sageresult
                publickey.q = publickey.n // publickey.p
                try:
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
                except NotImplementedError:
                    return (None, None)
            return (None, None)
        except KeyboardInterrupt:
            pass
        return (None, None)
Esempio n. 20
0
    def comfact(self, cipher, publickey):
        for c in cipher:
            commonfactor = gcd(publickey.n, s2n(c))

            if commonfactor > 1:
                publickey.q = commonfactor
                publickey.p = publickey.n // publickey.q
                priv_key = PrivateKey(
                    int(publickey.p),
                    int(publickey.q),
                    int(publickey.e),
                    int(publickey.n),
                )
                return (priv_key, None)
        return (None, None)
Esempio n. 21
0
 def attack(self, publickey, cipher=[], progress=True):
     """Try an attack where q < 100,000, from BKPCTF2016 - sourcekris"""
     with timeout(self.timeout):
         try:
             for prime in primes(100000):
                 if publickey.n % prime == 0:
                     publickey.q = prime
                     publickey.p = publickey.n // publickey.q
                     priv_key = PrivateKey(
                         int(publickey.p),
                         int(publickey.q),
                         int(publickey.e),
                         int(publickey.n),
                     )
                     return (priv_key, None)
         except TimeoutError:
             return (None, None)
     return (None, None)
Esempio n. 22
0
    def attack(self, publickey, cipher=[], progress=True):
        """Wiener's attack"""
        with timeout(self.timeout):
            try:
                wiener = WienerAttack(publickey.n, publickey.e, progress)
                if wiener.p is not None and wiener.q is not None:
                    publickey.p = wiener.p
                    publickey.q = wiener.q
                    priv_key = PrivateKey(
                        int(publickey.p),
                        int(publickey.q),
                        int(publickey.e),
                        int(publickey.n),
                    )
                    return (priv_key, None)
            except TimeoutError:
                return (None, None)

        return (None, None)
Esempio n. 23
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against fermat composites"""
     with timeout(self.timeout):
         try:
             limit = 10000
             p = q = None
             for x in tqdm(range(1, limit), disable=(not progress)):
                 f = gcd(fib(x), publickey.n)
                 if 1 < f < publickey.n:
                     p = publickey.n // f
                     q = f
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 24
0
    def attack(self, publickey, cipher=[], progress=True):
        """cm_factor attack"""
        D_candidates = [3, 11, 19, 43, 67, 163]
        sageresult = 0
        for D_candidate in tqdm(D_candidates, disable=(not progress)):
            try:
                sageresult = subprocess.check_output(
                    [
                        "sage",
                        "%s/sage/cm_factor.sage" % rootpath,
                        "-N",
                        str(publickey.n),
                        "-D",
                        str(D_candidate),
                    ],
                    timeout=self.timeout,
                    stderr=subprocess.DEVNULL,
                )
                if sageresult == b"Factorization failed\n":
                    continue
                X = str(sageresult).replace("'", "").split("\\n")
                X = list(filter(lambda x: x.find(" * ") > 0, X))
                if len(X) == 0:
                    continue
                sageresult = int(X[0].split(" ")[0])
                break
            except (
                    subprocess.CalledProcessError,
                    subprocess.TimeoutExpired,
                    ValueError,
            ):
                continue

        if isinstance(sageresult, int):
            if sageresult > 0:
                p = sageresult
                q = publickey.n // sageresult
                priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                      int(publickey.n))
                return (priv_key, None)

        return (None, None)
Esempio n. 25
0
    def attack(self, publickey, cipher=[], progress=True):
        """Do nothing, used for multi-key attacks that succeeded so we just print the
        private key without spending any time factoring
        """
        londahl_b = 20000000
        with timeout(self.timeout):
            try:
                factors = self.close_factor(publickey.n, londahl_b, progress)

                if factors is not None:
                    p, q = factors
                    priv_key = PrivateKey(
                        int(p), int(q), int(publickey.e), int(publickey.n)
                    )
                    return (priv_key, None)
                else:
                    return (None, None)
            except TimeoutError:
                return (None, None)
        return (None, None)
Esempio n. 26
0
 def attack(self, publickey, cipher=[], progress=True):
     """System primes in crypto constants"""
     with timeout(self.timeout):
         try:
             primes = load_system_consts()
             for prp in tqdm(primes, disable=(not progress)):
                 g = gcd(publickey.n, prp)
                 if publickey.n > g > 1:
                     publickey.q = g
                     publickey.p = publickey.n // publickey.q
                     priv_key = PrivateKey(
                         int(publickey.p),
                         int(publickey.q),
                         int(publickey.e),
                         int(publickey.n),
                     )
                     return (priv_key, None)
         except TimeoutError:
             return (None, None)
     return (None, None)
Esempio n. 27
0
    def attack(self, publickeys, cipher=[]):
        """Common factor attack"""
        if not isinstance(publickeys, list):
            return (None, None)

        with timeout(self.timeout):
            try:
                pubs = [pub.n for pub in publickeys]
                # Try to find the gcd between each pair of moduli and resolve the private keys if gcd > 1
                priv_keys = []
                M = ProductTree(pubs)
                for i in range(0, len(pubs) - 1):
                    pub = pubs[i]
                    x = publickeys[i]
                    R = M // pub
                    g = gcd(pub, R)
                    if pub > g > 1:
                        try:
                            p = g
                            q = pub // g
                            x.p = p
                            x.q = q
                            # update each attackobj with a private_key
                            priv_key_1 = PrivateKey(
                                int(x.p), int(x.q), int(x.e), int(x.n)
                            )
                            priv_keys.append(priv_key_1)

                            self.logger.info(
                                "[*] Found common factor in modulus for " + x.filename
                            )
                        except ValueError:
                            continue
            except TimeoutError:
                return (None, None)

        priv_keys = list(set(priv_keys))
        if len(priv_keys) == 0:
            priv_keys = None

        return (priv_keys, None)
Esempio n. 28
0
    def attack(self, publickey, cipher=[], progress=True):
        """ "primes" of the form 31337 - 313333337 - see ekoparty 2015 "rsa 2070"
        not all numbers in this form are prime but some are (25 digit is prime)
        """
        with timeout(self.timeout):
            try:
                maxlen = 25  # max number of digits in the final integer
                for i in tqdm(range(maxlen - 4), disable=(not progress)):
                    prime = int("3133" + ("3" * i) + "7")
                    if publickey.n % prime == 0:
                        publickey.p = prime
                        publickey.q = publickey.n // publickey.p
                        priv_key = PrivateKey(
                            p=int(publickey.p),
                            q=int(publickey.q),
                            e=int(publickey.e),
                            n=int(publickey.n),
                        )

                        return (priv_key, None)
            except TimeoutError:
                return (None, None)
        return (None, None)
Esempio n. 29
0
    def attack(self, publickey, cipher=[], progress=True):
        """Factors available online?"""
        with timeout(self.timeout):
            try:
                url_1 = "http://factordb.com/index.php?query=%i"
                url_2 = "http://factordb.com/index.php?id=%s"
                s = requests.Session()
                r = s.get(url_1 % publickey.n, verify=False)
                regex = re.compile(r"index\.php\?id\=([0-9]+)", re.IGNORECASE)
                ids = regex.findall(r.text)

                # check if only 1 factor is returned
                if len(ids) == 2:
                    # theres a chance that the only factor returned is prime, and so we can derive the priv key from it
                    regex = re.compile(r"<td>P<\/td>")
                    prime = regex.findall(r.text)
                    if len(prime) == 1:
                        # n is prime, so lets get the key from it
                        d = invmod(publickey.e, publickey.n - 1)
                        # construct key using only n and d
                        priv_key = PrivateKey(
                            e=int(publickey.e), n=int(publickey.n), d=d
                        )
                        return (priv_key, None)

                elif len(ids) == 3:
                    try:
                        regex = re.compile(r'value="([0-9\^\-]+)"', re.IGNORECASE)
                        p_id = ids[1]
                        r_1 = s.get(url_2 % p_id, verify=False)
                        key_p = regex.findall(r_1.text)[0]
                        publickey.p = (
                            int(key_p) if key_p.isdigit() else self.solveforp(key_p)
                        )

                        q_id = ids[2]
                        r_2 = s.get(url_2 % q_id, verify=False)
                        key_q = regex.findall(r_2.text)[0]
                        publickey.q = (
                            int(key_q) if key_q.isdigit() else self.solveforp(key_q)
                        )

                        if publickey.n != int(publickey.p) * int(publickey.q):
                            return (None, None)

                    except IndexError:
                        return (None, None)

                    try:
                        priv_key = PrivateKey(
                            p=int(publickey.p),
                            q=int(publickey.q),
                            e=int(publickey.e),
                            n=int(publickey.n),
                        )
                    except ValueError:
                        return (None, None)

                    return (priv_key, None)
                elif len(ids) > 3:
                    phi = 1
                    for p in ids[1:]:
                        phi *= int(p) - 1
                    d = invmod(publickey.e, phi)
                    plains = []

                    if cipher is not None and len(cipher) > 0:
                        for c in cipher:
                            int_big = int.from_bytes(c, "big")
                            plain1 = powmod(int_big, d, publickey.n)
                            plains.append(long_to_bytes(plain1))

                            return (None, plains)
                return (None, None)
            except NotImplementedError:
                return (None, None)
            except TimeoutError:
                return (None, None)
Esempio n. 30
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against mersenne primes"""
     with timeout(self.timeout):
         try:
             p = q = None
             mersenne_tab = [
                 2,
                 3,
                 5,
                 7,
                 13,
                 17,
                 19,
                 31,
                 61,
                 89,
                 107,
                 127,
                 521,
                 607,
                 1279,
                 2203,
                 2281,
                 3217,
                 4253,
                 4423,
                 9689,
                 9941,
                 11213,
                 19937,
                 21701,
                 23209,
                 44497,
                 86243,
                 110503,
                 132049,
                 216091,
                 756839,
                 859433,
                 1257787,
                 1398269,
                 2976221,
                 3021377,
                 6972593,
                 13466917,
                 20336011,
                 24036583,
                 25964951,
                 30402457,
                 32582657,
                 37156667,
                 42643801,
                 43112609,
                 57885161,
                 74207281,
                 77232917,
                 82589933,
             ]
             i = getpubkeysz(publickey.n)
             for mersenne_prime in tqdm(mersenne_tab,
                                        disable=(not progress)):
                 if mersenne_prime <= i:
                     m = (1 << mersenne_prime) - 1
                     if publickey.n % m == 0:
                         p = m
                         q = publickey.n // p
                         break
                 else:
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)