Exemplo n.º 1
0
    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

        if (
            d is None
            and self.p is not None
            and self.q is not None
            and self.e is not None
        ):
            t = (p - 1) * (q - 1)
            self.d = invmod(e, t)
        elif d is not None:
            self.d = d

        self.key = None
        if p is not None and q 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 ValueError:
                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
Exemplo n.º 2
0
    def close_factor(self, n, b, progress=True):
        # approximate phi
        phi_approx = n - 2 * isqrt(n) + 1

        # create a look-up table
        look_up = {}
        z = 1
        for i in tqdm(range(0, b + 1), disable=(not progress)):
            look_up[z] = i
            z = (z * 2) % n

        # check the table
        mu = invmod(powmod(2, phi_approx, n), n)
        fac = powmod(2, b, n)

        for i in tqdm(range(0, b + 1), disable=(not progress)):
            if mu in look_up:
                phi = phi_approx + (look_up[mu] - i * b)
                break
            mu = (mu * fac) % n
        else:
            return None

        m = n - phi + 1
        roots = ((m - isqrt(m**2 - 4 * n)) >> 1,
                 (m + isqrt(m**2 - 4 * n)) >> 1)

        if roots[0] * roots[1] == n:
            return roots
Exemplo n.º 3
0
def attack(attack_rsa_obj, publickey, cipher=[]):
    """Factors available online?
    """
    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 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 solveforp(
                    key_q)

            except IndexError:
                return (None, None)

            priv_key = PrivateKey(
                p=int(publickey.p),
                q=int(publickey.q),
                e=int(publickey.e),
                n=int(publickey.n),
            )

            return (priv_key, None)
        return (None, None)
    except:
        return (None, None)
Exemplo n.º 4
0
    def partial_q(self, e, dp, dq, qi, part_q, progress=True):
        """Search for partial q.
        Tunable to search longer.
        """
        N = 100000

        for j in tqdm(range(N, 1, -1), disable=(not progress)):
            q = (e * dq - 1) / j + 1
            if str(hex(q)).strip("L").endswith(part_q):
                break

        for k in tqdm(range(1, N, 1), disable=(not progress)):
            p = (e * dp - 1) / k + 1
            try:
                m = invmod(q, p)
                if m == qi:
                    break
            except:
                pass

        print("p = " + str(p))
        print("q = " + str(q))
Exemplo n.º 5
0
    def close_factor(self, n, b, progress=True):
        # approximate phi
        phi_approx = n - 2 * isqrt(n) + 1

        # create a look-up table
        look_up = {}
        z = 1
        for i in tqdm(range(0, b + 1), disable=(not progress)):
            look_up[z] = i
            z = (z << 1) % n

        # check the table
        mu = invmod(powmod(2, phi_approx, n), n)
        fac = powmod(2, b, n)

        for i in tqdm(range(0, b + 1), disable=(not progress)):
            if mu in look_up:
                phi = phi_approx + (look_up[mu] - (i * b))
                r = trivial_factorization_with_n_phi(n, phi)
                if r != None:
                    return r
            mu = (mu * fac) % n
        else:
            return None
Exemplo n.º 6
0
def print_results(args, publickey, private_key, uncipher):
    """Print results to output"""
    logger = logging.getLogger("global_logger")
    if ((args.private and private_key is not None) or (args.dumpkey)
            or (args.uncipher and uncipher not in [None, []])):
        if publickey is not None:
            logger.info("\nResults for %s:" % publickey)
    if private_key is not None:
        if not isinstance(private_key, list):
            private_keys = [private_key]
        else:
            private_keys = private_key

        if args.private:
            logger.info("\nPrivate key :")
            for priv_key in private_keys:
                if priv_key is not None:
                    if args.output:
                        try:
                            with open(args.output, "a") as output_fd:
                                output_fd.write("%s\n" % str(priv_key))
                        except:
                            logger.error("Can't write output file : %s" %
                                         args.output)
                    if str(priv_key) != "":
                        logger.info(priv_key)
                    else:
                        logger.warning(
                            "Key format seems wrong, check input data to solve this."
                        )

        if args.dumpkey:
            for priv_key in private_keys:
                if priv_key.n is not None:
                    logger.info("n: " + str(priv_key.n))
                if priv_key.e is not None:
                    logger.info("e: " + str(priv_key.e))
                if priv_key.d is not None:
                    logger.info("d: " + str(priv_key.d))
                if priv_key.p is not None:
                    logger.info("p: " + str(priv_key.p))
                if priv_key.q is not None:
                    logger.info("q: " + str(priv_key.q))
                if args.ext:
                    dp = priv_key.d % (priv_key.p - 1)
                    dq = priv_key.d % (priv_key.q - 1)
                    pinv = invmod(priv_key.p, priv_key.q)
                    qinv = invmod(priv_key.q, priv_key.p)
                    logger.info("dp: " + str(dp))
                    logger.info("dq: " + str(dq))
                    logger.info("pinv: " + str(pinv))
                    logger.info("qinv: " + str(qinv))
    else:
        if args.private:
            logger.critical("Sorry, cracking failed.")

    if args.dumpkey:
        if args.publickey is not None:
            for public_key in args.publickey:
                with open(public_key, "rb") as pubkey_fd:
                    publickey_obj = PublicKey(pubkey_fd.read(), publickey)
                    logger.info("\nPublic key details for %s" %
                                publickey_obj.filename)
                    logger.info("n: " + str(publickey_obj.n))
                    logger.info("e: " + str(publickey_obj.e))

    if args.uncipher:
        if uncipher is not None:
            if not isinstance(uncipher, list):
                uncipher = [uncipher]
            if len(uncipher) > 0:
                logger.info("\nUnciphered data :")
                for uncipher_ in uncipher:
                    if not isinstance(uncipher_, list):
                        uncipher_ = [uncipher_]

                    for c in uncipher_:
                        if args.output:
                            try:
                                with open(args.output, "ab") as output_fd:
                                    output_fd.write(c)
                            except:
                                logger.error("Can't write output file : %s" %
                                             args.output)

                        logger.info(f"HEX : 0x{c.hex()}")

                        int_big = int.from_bytes(c, "big")
                        int_little = int.from_bytes(c, "little")

                        logger.info(f"INT (big endian) : {int_big}")
                        logger.info(f"INT (little endian) : {int_little}")
                        try:
                            c_utf8 = c.decode("utf-8")
                            logger.info(f"utf-8 : { c_utf8 }")
                        except UnicodeDecodeError:
                            pass
                        try:
                            c_utf16 = c.decode("utf-16")
                            logger.info(f"utf-16 : { c_utf16 }")
                        except UnicodeDecodeError:
                            pass
                        logger.info(f"STR : {repr(c)}")
        else:
            logger.critical("Sorry, unciphering failed.")
Exemplo n.º 7
0
        exit(0)

    # if dumpkey mode dump the key components then quit
    if args.key is not None and args.dumpkey:
        key_data = open(args.key, "rb").read()
        key = RSA.importKey(key_data)
        print("n: " + str(key.n))
        print("e: " + str(key.e))
        if key.has_private():
            print("d: " + str(key.d))
            print("p: " + str(key.p))
            print("q: " + str(key.q))
            if args.ext:
                dp = key.d % (key.p - 1)
                dq = key.d % (key.q - 1)
                pinv = invmod(key.p, key.q)
                qinv = invmod(key.q, key.p)
                print("dp: " + str(dp))
                print("dq: " + str(dq))
                print("pinv: " + str(pinv))
                print("qinv: " + str(qinv))

        exit(0)

    if args.key is not None and args.isconspicuous:
        with open(args.key, "rb") as key_fp:
            key_data = key_fp.read()
            key = RSA.importKey(key_data)
            try:
                pub_key, priv_key = generate_keys_from_p_q_e_n(
                    args.p, args.q, args.e, args.n
Exemplo n.º 8
0
    def attack(self, publickey, cipher=[]):
        """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 = []
                    for c in cipher:
                        int_big = int.from_bytes(c, "big")
                        plain1 = pow(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)
Exemplo n.º 9
0
def print_results(args, publickey, private_key, uncipher):
    """ Print results to output
    """
    logger = logging.getLogger("global_logger")
    if ((args.private and private_key is not None) or (args.dumpkey)
            or (args.uncipher and uncipher not in [None, []])):
        if publickey is not None:
            logger.info("\nResults for %s:" % publickey)
    if private_key is not None:
        if not isinstance(private_key, list):
            private_keys = [private_key]
        else:
            private_keys = private_key

        if args.private:
            logger.info("\nPrivate key :")
            for priv_key in private_keys:
                if priv_key is not None:
                    if args.output:
                        try:
                            with open(args.output, "a") as output_fd:
                                output_fd.write("%s\n" % str(priv_key))
                        except:
                            logger.error("Can't write output file : %s" %
                                         args.output)
                    logger.info(priv_key)

        if args.dumpkey:
            for priv_key in private_keys:
                if priv_key.n is not None:
                    logger.info("n: " + str(priv_key.n))
                if priv_key.e is not None:
                    logger.info("e: " + str(priv_key.e))
                if priv_key.d is not None:
                    logger.info("d: " + str(priv_key.d))
                if priv_key.p is not None:
                    logger.info("p: " + str(priv_key.p))
                if priv_key.q is not None:
                    logger.info("q: " + str(priv_key.q))
                if args.ext:
                    dp = priv_key.d % (priv_key.p - 1)
                    dq = priv_key.d % (priv_key.q - 1)
                    pinv = invmod(priv_key.p, priv_key.q)
                    qinv = invmod(priv_key.q, priv_key.p)
                    logger.info("dp: " + str(dp))
                    logger.info("dq: " + str(dq))
                    logger.info("pinv: " + str(pinv))
                    logger.info("qinv: " + str(qinv))
    else:
        if args.private:
            logger.critical("Sorry, cracking failed.")

    if args.dumpkey:
        if args.publickey is not None:
            for public_key in args.publickey:
                with open(public_key, "rb") as pubkey_fd:
                    publickey_obj = PublicKey(pubkey_fd.read(), publickey)
                    logger.info("\nPublic key details for %s" %
                                publickey_obj.filename)
                    logger.info("n: " + str(publickey_obj.n))
                    logger.info("e: " + str(publickey_obj.e))

    if args.uncipher:
        if uncipher is not None:
            if not isinstance(uncipher, list):
                uncipher = [uncipher]
            if len(uncipher) > 0:
                logger.info("\nUnciphered data :")
                for uncipher_ in uncipher:
                    if args.output:
                        try:
                            with open(args.output, "ab") as output_fd:
                                output_fd.write(uncipher_)
                        except:
                            logger.error("Can't write output file : %s" %
                                         args.output)
                    logger.info(uncipher_)
        else:
            logger.critical("Sorry, unciphering failed.")