Алгоритмы с открытым ключом используют различные ключи для шифрования и дешифрования, при этом ключ дешифрования практически невозможно восстановить по ключу шифрования. Методы с открытым ключом важны, поскольку они могут использоваться для передачи шифровальных ключей или другой информации защищенным способом даже если стороны не имели возможности договориться частным образом об общем секретном ключе. Все известные методы довольно медленны и обычно используются только для шифровки ключей сессии (которые представляют собой сгенерированные случайным образом "нормальные" ключи), которые затем используются при шифровании тела сообщения с помощью симметричного шифра.


RSA

RSA (Rivest-Shamir-Adelman) является наиболее известным алгоритмом с открытым ключом. Может использоваться как для шифрования, так и для создания подписи. Считается, что алгоритм надежен при использовании достаточно длинных ключей (значение 512 бит считается недостаточным, 768 бит - умеренно надежным, 1024 бит - хорошим). Безопасность RSA основана на проблеме факторизации больших целых чисел. Существенные продвижения в способах факторизации больших чисел могут сделать метод RSA уязвимым. В настоящее время RSA является наиболее важным алгоритмом с открытым ключом.

RSA использует операцию возведения в степень (мы будем обозначать эту операцию символом ^) по модулю для шифровки и дешифровки сообщения, которое получается путем перевода текста в цифровую форму (если речь идет о компьютерах, то текст и так имеет цифровую форму, так что данное замечание тривиально).

Алгоритм RSA и генерация ключей

Функция шифровки, используемая в RSA, выглядит так: C = T^E mod N, где T представляет собой шифруемый текст, C - зашифрованный текст, а E представляет собой открытый ключ. Другими словами, T возводится в степень E по модулю N. Для примера, 2 в степени 3 дает 8, а 2 в степени3 по модулю 7 есть 8 mod 7, что равно 1. Функция дешифрования выглядит так: T = C^D mod N где D представляет собой секретный ключ. Пара ключей E и D должна быть выбрана так, что E является обратным к D по отношению к операции возведения в степень по модулю N. Иными словами, (T^E mod N)^D mod N = T^ED mod N = T.

Для того, чтобы найти подходящую пару, для которой это равенство верно, нам надо знать функцию Эйлера переноса (Euler's totient function), J(N) для данного значения модуля N. Функция Эйлера представляет собой количество чисел в интервале от 1 до N-1, которые являются простыми относительно N. Для нахождения функции J(N) нaдо, в свою очередь, найти простые факторы N.

Фундаментальная теорема арифметики: Любое не простое число может быть представлено как произведение уникального набора простых чисел.

Относительно простые числа: Два числа называются относительно простыми, если среди их простых факторов нет одинаковых.

Итак, нам надо найти набор простых факторов числа N для того, чтобы вычислить функцию Эйлера. J(N). Нахождение этих факторов является задачей чрезвычайно сложной - практически абсолютно невозможно для достаточно больших N, и именно этот факт и делает PGP таким надежным методом шифрования. Для заданных N и E вы не можете найти D (и, таким образом, расшифровать сообщение) не зная простых факторов числа N, что настолько трудно, что PGP является виртуально невскрываемой при достаточно больших N.

Практический способ сгенерировать пару ключей - это сначала сгенерировать само N путем умножения двух больших простых чисел P и Q, так что простые факторы N мы уже знаем. Для числа, которое имеет только два простых фактора (как в нашем случае), функция Эйлера равна: J(N) = (P-1)(Q-1)

Теперь мы выбирает некоторое число E, которое является простым относительно J(N) (зачем нам это условие мы увидим ниже). Нам надо найти D, которое является обратным к E по отношению к операции возведения в степень по модулю N. Это можно сделать, зная J(N).

 Имеется правило в модульной арифметике, гласящее, что если операция возведения в степень использует модуль N, то показатели экспонент должны использовать модуль J(N). Например рассмотрим, (T^E mod N)^D mod N = T^ED mod N

Оказывается, что умножать показатели степени E и D мы должны с использованием mod J(N), а не mod N. Для того, чтобы для заданного показателя шифровки E найти подходящее обратное число D, нам следует удовлетворить равенство: T^ED mod N = T

 Для этого достаточно, чтобы ED mod J(N) = 1, так как T^1 mod N = T. Так что проблема нахождения D сводится к проблеме нахождения числа, обратного E по модулю J(N), что с вычислительной точки зрения тривиально. Следует отметить, что в модульной арифметике есть закон, гласящий, что для заданного модуля M число может иметь обратное относительно операции умножения по модулю M только если оно является относительно простым по отношению к M. Вот почему мы выбирали E как не имеющее общих простых факторов с J(N), так, чтобы у него имелось обратное D по модулю J(N). Тривиальные комбинации E и D (например E = D) отбрасываются как неподходящие с точки зрения секретности, и тогда выбираем новое E.

Когда мы выбрали значение N и сгенерировали наши ключи E и D, можно забыть о P, Q и J(N), так как они сделали свое дело. Мы имеем подходящие ключи шифровки и дешифровки E и D
C = T^E mod N and T = C^D mod N (на самом деле совершенно не важно какой из ключей D или E считается ключом шифровки). Не зная чисел P и Q практически невозможно вычислить J(N) и, следовательно, найти D по заданному E при больших значениях N, так что шифрование является надежным.

Итоговый список шагов, необходимых для генерации ключа

  • Выбираем пару произвольных больших простых чисел P и Q и находим N путем умножения
  • Вычисляем функцию Эйлера числа N, J(N) = (P-1)(Q-1)
  • Выбираем число E так, чтобы оно было относительно простым по отношению к J(N)
  • Находим D, обратное число к E по отношению к операции умножения по модулю J(N), и тривиальные значения отбраковываем как несекретные (E=D)
  • Найдя подходящую пару ключей, ключ E объявляем открытым и его можно использовать для шифровки сообщений, адресованных владельцу пары E и D: C = T^E mod N
  • Ключ D держится в секрете и используется для дешифровки полученных сообщений: T = C^D mod N
  • Надежность RSA

    Факторизация N приведет к вскрытию алгоритма RSA. Не было доказано, что нет полиномиального по затратам времени решения задачи нахождения простых факторов большого числа (то есть возможно, что в будущем будет найден алгоритм, который факторизует N достаточно быстро для вскрытия RSA). Однако, несмотря на постоянное продвижение в алгоритмах факторизации, ни один из них не удовлетворяет критерию полиномиальности по времени, что сделало бы проблему RSA разрешимой.

    Важно отметить, что не было доказано, что безопасность RSA целиком зависит от проблемы нахождения простых факторов большого числа. Однако все другие способы нахождения D по заданному E оказались эквивалентны по затратам задаче факторизации N. Есть вероятность, что будет найден алгоритм для нахождения E-того корня по модулю N более простым путем, чем факторизация N. Тем не менее, до сих пор не был найден такой алгоритм и RSA выдержал огромное число попыток вскрытия.

    Контрольные вопросы.

    1. Что делает алгоритм RSA неуязвимым?
    2. Какие операции использует этот алгоритм?
    3. Объясните каждый шаг, необходимый для генерации ключа.