Как найти простые множители числа с помощью python

Я пишу программу, которая будет вычислять закрытый ключ для слабого открытого ключа RSA. Мне интересно, как я буду определять значения для p и q из значения n. Вот код Python на данный момент:

from Crypto.PublicKey import RSA #PyCryptoDome
import .math as cm # My own module

with open(public_keyfile, 'rb') as key: # Public Keyfile Is in PEM format
    public_key = RSA.import_key(key)

n = public_key.n # N value of the public_key

e = public_key.e # E value of the public_key

p, q = get_factors_of(n) # This I don't know how to do, though there is a question that might help [see bottom]

t = cm.lcm(p-1, q-1) # Get the lowest common multiple of q and q

d = cm.mod_inverse(e, t) # Get d, the modular inverse of e % t

private_key = RSA.construct((n, e, d, p, q) # Construct the RSA private_key

Модуль .math, упомянутый выше:

from math import gcd


def mod_inverse(a, b):
    a = a % b
    for x in range(1, b):
        if (a * x) % b == 1:
            return x
    return 1


def lcm(x, y):
    return x * y // gcd(x, y)

То, что мне нужно сделать, похоже, упоминается здесь, но этот код на Java.

Если кто-нибудь знает, как получить p и q из n с помощью python, помощь будет оценена по достоинству.

Большое спасибо, Легорой.

SO не является бесплатной службой преобразования кода. Сделайте преобразование в Python, затем опубликуйте свой код с вопросами.

lit 06.06.2019 11:54

Я знаю. Я вообще не понимаю Java, я надеялся, что SO сможет помочь с тем, как получить p и q из n с помощью python.

Legorooj 06.06.2019 11:57

Вы понимаете, как это сделать вручную? Если нет, то у вас действительно вопрос по математике, а не по программированию (и уж тем более не по Python). Если вы это сделаете, начните с этого и задайте более конкретный вопрос, если вы не можете заставить реализацию работать.

Karl Knechtel 06.06.2019 11:59

Я не думаю, что вы понимаете сложность факторизации больших целых чисел, которые являются произведениями двух приблизительно равных простых чисел, то есть модулей RSA. Без большого количества оборудования и/или времени вы не сможете это сделать.

President James K. Polk 06.06.2019 16:43

К счастью, у меня есть оба. @KarlKnechtel, я понимаю, как это сделать вручную, и нашел способ реализовать это - пока только в виде псевдокода. Если это сработает, я отвечу на свой вопрос. Если нет, я задам новый вопрос о том, почему внедрение не работает.

Legorooj 06.06.2019 20:45
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
4 113
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обязательное предупреждение: если вам нужна производительность, вам нужно будет самостоятельно изучить детали алгоритмов. Даже «слабые» открытые ключи будут взламываться вечно с помощью упрощенного алгоритма (например, решета Эратостена).

При этом sympy.ntheory.factorint() может быть тем, что вам нужно:

from sympy.ntheory import factorint

print(factorint(54))  # {2: 1, 3: 3} i.e. 54 == 2**1 * 3**3

Спасибо за этот ответ, но smpy.ntheory.factorint() занимает слишком много времени с этим тестовым числом: 923637899768568287772166109497249792403968575282737183332732‌​27103233778958409026‌​38303442492100881746‌​87818638624438313518‌​65870040522711807809‌​32725919664899

Legorooj 06.06.2019 13:15
math.log(your number, 2) возвращает ~ 512. Опять же, даже «слабый» открытый ключ будет взломан целую вечность. Страница Википедии en.wikipedia.org/wiki/… заставляет меня думать, что RSA-512 по-прежнему является крепким орешком для одного случайного парня, использующего Python, даже если его использование небезопасно (потому что злоумышленники — теоретики чисел с доступом к приличному оборудованию).
Leporello 06.06.2019 13:22

Также возникает вопрос о том, для чего вы используете свою программу, так как я уверен, что есть некоторые компании, которые все еще используют RSA-512...

Leporello 06.06.2019 13:25

Я собираюсь использовать свою программу для атаки на рецепт шифра, который я придумал - тот, который не отличается от pgp.

Legorooj 06.06.2019 13:48
Ответ принят как подходящий

После долгих поисков в Google и чтения PDF-файлов я нашел алгоритм, который работает. Вот реализация на питоне:

import math
def get_factors_of(num):
    poss_p = math.floor(math.sqrt(num)) 

    if poss_p % 2 == 0: # Only checks odd numbers, it reduces time by orders of magnitude
        poss_p += 1
    while poss_p < num:
        if num % poss_p == 0:
            return poss_p
        poss_p += 2

Этот алгоритм эффективно находит коэффициенты P/Q небольшого ключа RSA. (Я протестировал его на 64-битном открытом ключе PEM)

Другие вопросы по теме