EssayAI
Блог
Блог

Как сгенерировать ключи RSA: пример на малых числах

Запрос

Дано: простые числа p=43p = 43 и q=59q = 59, открытая экспонента e=13e = 13, сообщение m=1234m = 1234. Найти: открытый и закрытый ключи RSA, шифртекст и проверку расшифровкой.

Пара ключей собирается из четырёх чисел: модуль n=pqn = pq, значение функции Эйлера φ(n)=(p−1)(q−1)\varphi(n) = (p-1)(q-1), открытая экспонента ee и обратная к ней по модулю φ(n)\varphi(n) закрытая экспонента dd. Ответ: открытый ключ (2537, 13)(2537,\ 13), закрытый ключ (2537, 937)(2537,\ 937), шифртекст c=2391c = 2391. Калькулятор сверху пересчитает всю пару под другие простые и другое сообщение, ниже - решение по шагам.

Решение по шагам

Шаг 1. Модуль. Перемножаем простые:

n=pq=43⋅59=2537.n = pq = 43 \cdot 59 = 2537.

Модуль публикуется открыто, а вот сами множители 43 и 59 с этого момента становятся секретом: именно из них считается всё остальное.

Шаг 2. Значение функции Эйлера. Для произведения двух различных простых оно считается по формуле:

φ(n)=(p−1)(q−1)=42⋅58=2436.\varphi(n) = (p-1)(q-1) = 42 \cdot 58 = 2436.

Это число знает только владелец ключа. Тот, кто видит лишь n=2537n = 2537, посчитать φ(n)\varphi(n) не может, не разложив модуль на множители.

Шаг 3. Проверка открытой экспоненты. Экспонента ee годится, если она взаимно проста с φ(n)\varphi(n), то есть gcd⁡(e,φ(n))=1\gcd(e, \varphi(n)) = 1. Прогоняем алгоритм Евклида для пары 2436 и 13:

2436=187⋅13+5,13=2⋅5+3,5=1⋅3+2,3=1⋅2+1,2=2⋅1+0.\begin{aligned} 2436 &= 187 \cdot 13 + 5, \\ 13 &= 2 \cdot 5 + 3, \\ 5 &= 1 \cdot 3 + 2, \\ 3 &= 1 \cdot 2 + 1, \\ 2 &= 2 \cdot 1 + 0. \end{aligned}

Последний ненулевой остаток равен единице, значит e=13e = 13 подходит. Подробный разбор самого алгоритма с делениями и коэффициентами Безу лежит в разборе как найти НОД двух чисел, здесь он нужен как проверка.

Шаг 4. Закрытая экспонента. Разворачиваем цепочку делений снизу вверх, выражая единицу через 13 и 2436:

1=3−1⋅2=3−(5−3)=2⋅3−5,=2⋅(13−2⋅5)−5=2⋅13−5⋅5,=2⋅13−5⋅(2436−187⋅13)=937⋅13−5⋅2436.\begin{aligned} 1 &= 3 - 1 \cdot 2 = 3 - (5 - 3) = 2 \cdot 3 - 5, \\ &= 2 \cdot (13 - 2 \cdot 5) - 5 = 2 \cdot 13 - 5 \cdot 5, \\ &= 2 \cdot 13 - 5 \cdot (2436 - 187 \cdot 13) = 937 \cdot 13 - 5 \cdot 2436. \end{aligned}

Коэффициент при 13 и есть искомое: d=937d = 937. Проверка занимает строчку: 13⋅937=12181=5⋅2436+113 \cdot 937 = 12181 = 5 \cdot 2436 + 1, то есть ed≡1(mod2436)ed \equiv 1 \pmod{2436}.

Шаг 5. Шифрование. Шифртекст считается как c=me mod nc = m^e \bmod n. Возводить 1234 в тринадцатую степень целиком нельзя - число не влезет ни в какой калькулятор, поэтому берём последовательные квадраты по модулю 2537:

Степень1248
Остаток по модулю 253712345562159812

Показатель раскладывается в сумму степеней двойки: 13=8+4+113 = 8 + 4 + 1, поэтому перемножаем три остатка из таблицы:

c=812⋅2159⋅1234 mod 2537=41⋅1234 mod 2537=2391.c = 812 \cdot 2159 \cdot 1234 \bmod 2537 = 41 \cdot 1234 \bmod 2537 = 2391.

Техника подробно разобрана в задаче как быстро возвести в степень - без неё ручной счёт в RSA невозможен.

Шаг 6. Проверка расшифровкой. Расшифровка устроена симметрично: m=cd mod nm = c^d \bmod n. Показатель 937 в двоичной записи равен 1110101001, то есть девять возведений в квадрат и пять домножений - четырнадцать умножений по модулю. Результат: 2391937 mod 2537=12342391^{937} \bmod 2537 = 1234, исходное число восстановилось.

Ответ. Открытый ключ (n,e)=(2537, 13)(n, e) = (2537,\ 13), закрытый ключ (n,d)=(2537, 937)(n, d) = (2537,\ 937), шифртекст сообщения 1234 равен 2391, обратное преобразование даёт исходное 1234.

Формула: почему расшифровка возвращает исходное число

Всё держится на одном условии, наложенном при выборе dd:

ed≡1(modφ(n)),то естьed=1+kφ(n).ed \equiv 1 \pmod{\varphi(n)}, \qquad \text{то есть} \qquad ed = 1 + k\varphi(n).

В нашем случае k=5k = 5: произведение 12181 ровно на единицу больше, чем пять раз по 2436. Подставим это в цепочку преобразований и посмотрим, что происходит с сообщением:

(me)d=med=m1+kφ(n)=m⋅(mφ(n))k.(m^e)^d = m^{ed} = m^{1 + k\varphi(n)} = m \cdot \left(m^{\varphi(n)}\right)^{k}.

Дальше работает теорема Эйлера: если mm и nn взаимно просты, то mφ(n)≡1(modn)m^{\varphi(n)} \equiv 1 \pmod{n}. Скобка обращается в единицу, и справа остаётся само mm. Никакой магии в схеме нет: закрытая экспонента просто «доводит» показатель до величины, кратной φ(n)\varphi(n), плюс один.

Отдельно стоит редкий случай, когда сообщение делится на pp или на qq. Тогда теорема Эйлера напрямую не применима, но равенство всё равно выполняется - это проверяется малой теоремой Ферма по каждому простому множителю отдельно и китайской теоремой об остатках. Практического значения этот случай не имеет: угадать кратное pp сообщение не проще, чем разложить модуль.

Как выбирать открытую экспоненту

Требование к ee ровно одно: 1<e<φ(n)1 < e < \varphi(n) и gcd⁡(e,φ(n))=1\gcd(e, \varphi(n)) = 1. Если общий делитель есть, обратного элемента не существует, и расширенный алгоритм Евклида честно вернёт вместо единицы этот делитель. Переключи график калькулятора в режим выбора экспоненты: зелёные столбики - кандидаты с НОД, равным единице, оранжевые не подходят.

Для φ(n)=2436=22⋅3⋅7⋅29\varphi(n) = 2436 = 2^2 \cdot 3 \cdot 7 \cdot 29 отпадают все чётные числа, а также кратные 3, 7 и 29. Поэтому популярное e=3e = 3 здесь тоже пришлось бы отбросить: тройка делит 2436. Число 13 в этот список не попадает и годится.

На практике экспоненту не ищут перебором, а берут одну из двух: e=65537=216+1e = 65537 = 2^{16} + 1 почти всегда, реже e=3e = 3. Причина простая: в двоичной записи 65537 всего две единицы, поэтому шифрование стоит семнадцать умножений независимо от длины ключа. А вот dd маленьким быть не должен - при d<n1/4d < n^{1/4} ключ восстанавливается атакой Винера за считанные секунды.

Что меняется на настоящих ключах

Числа 43 и 59 годятся только для тетради. В боевом ключе pp и qq - случайные простые примерно по 1024 бита, чтобы модуль вышел на 2048 бит. Ищут их так: генерируют случайное нечётное число нужной длины и проверяют вероятностным тестом, а перебор делителей до корня, описанный в разборе как проверить число на простоту, для таких размеров не годится совсем.

Второе отличие - вместо φ(n)\varphi(n) чаще берут функцию Кармайкла λ(n)=lcm⁡(p−1,q−1)\lambda(n) = \operatorname{lcm}(p-1, q-1). Условие ed≡1(modλ(n))ed \equiv 1 \pmod{\lambda(n)} слабее, поэтому dd ищется в меньшем диапазоне и в среднем выходит короче, а расшифровка быстрее. Для нашей пары λ(2537)=lcm⁡(42,58)=1218\lambda(2537) = \operatorname{lcm}(42, 58) = 1218, и обратный к 13 по этому модулю - то же самое число 937: оно и так меньше 1218, выигрыша на учебных числах не видно. Третье - сообщение никогда не шифруют «как есть»: перед возведением в степень к нему добавляют случайное дополнение по схеме OAEP, иначе одинаковые сообщения давали бы одинаковые шифртексты.

Стойкость же целиком сводится к сложности разложения модуля. Зная pp и qq, любой посчитает φ(n)\varphi(n) и повторит шаг 4 - наш n=2537n = 2537 раскладывается перебором за доли секунды, о чём подробно в разборе как найти простые множители. Для 2048 бит классических методов не хватает, но квантовый алгоритм Шора сводит факторизацию к поиску периода и решает задачу за полиномиальное время - поэтому RSA и считают схемой с ограниченным сроком годности.

До появления асимметричной криптографии стойкость искали в длине ключа: у шифра Виженера ключ-слово растягивали на весь текст, и именно повторяемость ключа его и погубила.

Частые ошибки

  • Считают φ(n)\varphi(n) от произведения, а не от множителей. Формула φ(n)=(p−1)(q−1)\varphi(n) = (p-1)(q-1) работает только для двух различных простых. Брать n−1=2536n - 1 = 2536 вместо 2436 - самая частая ошибка в контрольных, и дальше всё расчётное дерево уезжает.
  • Берут p=qp = q. При совпадении множителей формула другая: φ(p2)=p(p−1)\varphi(p^2) = p(p-1), а сам модуль раскладывается извлечением квадратного корня. Простые обязаны быть разными.
  • Ищут dd по модулю nn вместо φ(n)\varphi(n). Обратный элемент к 13 берётся по модулю 2436, а не 2537. Число получится другое, и проверка расшифровкой не сойдётся.
  • Не приводят отрицательный коэффициент. Расширенный алгоритм Евклида часто выдаёт dd со знаком минус; к нему нужно прибавить φ(n)\varphi(n), чтобы попасть в диапазон от 1 до φ(n)\varphi(n).
  • Возводят в степень без приведения по модулю. Число 1234131234^{13} имеет 41 знак. Остаток берут после каждого умножения, иначе даже учебный пример не считается.
  • Шифруют сообщение, большее модуля. Условие m<nm < n обязательно: при m≥nm \ge n расшифровка вернёт остаток m mod nm \bmod n, а не исходное число. Длинные сообщения режут на блоки.

FAQ

Какие числа входят в открытый ключ, а какие в закрытый? Открытый ключ - пара (n,e)(n, e), её можно публиковать. Закрытый - пара (n,d)(n, d). Простые pp, qq и значение φ(n)\varphi(n) уничтожают или хранят вместе с закрытым ключом: по любому из них dd восстанавливается за один прогон алгоритма Евклида.

Обязательно ли ee должно быть простым числом? Нет. Требуется только взаимная простота с φ(n)\varphi(n). Само ee может быть составным, например e=25e = 25, если φ(n)\varphi(n) не делится на 5. Простые значения берут потому, что для них проверка НОД сводится к одному делению.

Почему нельзя вычислить dd, зная только открытый ключ? Для поиска dd нужно φ(n)\varphi(n), а для него - разложение nn на множители. Обратная задача к умножению двух больших простых чисел и есть узкое место: перемножить их легко, разложить произведение обратно - вычислительно тяжело.

Что будет, если два человека случайно возьмут одно и то же простое? Их модули n1n_1 и n2n_2 получат общий делитель, и алгоритм Евклида найдёт его мгновенно, вскрыв оба ключа. Такие коллизии в реальных наборах ключей находили массово, поэтому качество генератора случайных чисел здесь важнее длины ключа.

Коротко

  1. Взять два различных простых pp и qq и посчитать модуль n=pqn = pq: 43⋅59=253743 \cdot 59 = 2537.
  2. Найти значение функции Эйлера φ(n)=(p−1)(q−1)=42⋅58=2436\varphi(n) = (p-1)(q-1) = 42 \cdot 58 = 2436 и держать его в секрете.
  3. Выбрать открытую экспоненту ee так, чтобы gcd⁡(e,φ(n))=1\gcd(e, \varphi(n)) = 1: для e=13e = 13 алгоритм Евклида даёт единицу.
  4. Вычислить закрытую экспоненту как обратный элемент: d=e−1 mod φ(n)=937d = e^{-1} \bmod \varphi(n) = 937, проверка 13⋅937=5⋅2436+113 \cdot 937 = 5 \cdot 2436 + 1.
  5. Шифровать как c=me mod nc = m^e \bmod n, расшифровывать как m=cd mod nm = c^d \bmod n: сообщение 1234 превращается в 2391 и обратно.
Задача в тетради или методичке? Сфотографируйте условие - сервис распознает его и решит по шагам с пояснениями.

Похожие задачи

Теория чисел/криптография

Как найти обратное по модулю: расширенный алгоритм Евклида

Как найти обратное по модулю: разбор на числах 37 и 120, условие существования через НОД, таблица расширенного алгоритма Евклида, приведение коэффициента и проверка остатка.

Теория чисел/криптография

Как найти функцию Эйлера: разбор на числе 7560

Как найти функцию Эйлера: разбор числа 7560 по шагам, каноническое разложение, формула через произведение скобок по простым делителям, проверка мультипликативностью и теорема Эйлера.

Теория чисел/криптография

Как найти первообразный корень: критерий и пример

Как найти первообразный корень по модулю: функция Эйлера, критерий через её простые делители, проверка кандидатов 2, 3, 5 и 6 по модулю 41 и таблица индексов.

Теория чисел/криптография

Как решить систему сравнений: китайская теорема об остатках

Как решить систему сравнений x = 2 (mod 3), x = 3 (mod 5), x = 2 (mod 7): проверка взаимной простоты модулей, сборка ответа по китайской теореме об остатках и проверка подстановкой.

Теория чисел/криптография

Как решить сравнение по модулю: 42x = 30 (mod 78)

Как решить сравнение по модулю на примере 42x = 30 (mod 78): критерий разрешимости через НОД, число решений, сокращение сравнения вместе с модулем и все шесть классов вычетов.

Теория чисел/криптография

Как найти НОК двух чисел: два способа с примером

Как найти НОК двух чисел на примере 126 и 120: разложение на простые множители со старшими степенями, формула через НОД, проверка ответа и задача про шестерни с зубьями.