Использовать закрытый ключ RSA для генерации открытого ключа?


394

Я не очень понимаю это:

Согласно: http://www.madboa.com/geek/openssl/#key-rsa , Вы можете создать открытый ключ из закрытого ключа.

openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -pubout > mykey.pub

Сначала я думал, что они создаются в паре вместе. Закрытый ключ RSA содержит сумму? или открытый ключ?


1
Каждому, кто использует rsa и openssl и хочет зашифровать большой файл размером 5 Кбайт. Пожалуйста, помните, что открытый ключ должен быть пропорционален или больше по размеру тому, что вы хотите зашифровать, иначе вы получите «файл большого размера, который будет зашифрован». Подводя итог, вы генерируете довольно большой и серьезный закрытый ключ и из этого делаете свои закрытые ключи, чтобы у вас было много данных для работы. Я рассказал кому-то в openssl о недостатке, и что они должны просто сделать его самим, иначе вы потратите много времени на выяснение причин, по которым он жалуется на размер.
Кент Хансен

10
Проблема, описанная Кентом Хансеном, связана с использованием RSA непосредственно в незашифрованных данных, что ни в коем случае нельзя делать из соображений безопасности. Вместо этого используйте хорошо проанализированную гибридную схему шифрования, такую ​​как RSA-KEM ( tools.ietf.org/html/rfc5990#appendix-A ), с аутентифицированной симметричной схемой шифрования, такой как encrypt-then-HMAC, примененной к данным.
Дайра Хопвуд

Это может помочь: jason4zhu.blogspot.jp/2014/10/…
Судя


Ответ @ SteffenUllrich по этой ссылке объясняет, почему: security.stackexchange.com/questions/172274/…
bearzyj

Ответы:


578
openssl genrsa -out mykey.pem 1024

фактически создаст пару открытый - закрытый ключ. Пара сохраняется в сгенерированном mykey.pemфайле.

openssl rsa -in mykey.pem -pubout > mykey.pub

извлечет открытый ключ и распечатает его. Вот ссылка на страницу, которая описывает это лучше.

РЕДАКТИРОВАТЬ: Проверьте раздел примеров здесь . Чтобы просто вывести открытую часть закрытого ключа:

openssl rsa -in key.pem -pubout -out pubkey.pem

Чтобы получить пригодный для использования открытый ключ для целей SSH, используйте ssh-keygen :

ssh-keygen -y -f key.pem > key.pub

50
сбивает с толку, как все в учебниках повсюду говорят, что с помощью команды openssl genrsa вы сгенерируете PRIVATE KEY, потому что они забывают, что она также генерирует PUBLIC KEY
Jaime Hablutzel

15
@ Джайм, можешь ли ты их винить? Официальная документация абсолютно ничего не говорит об открытом ключе. «ОПИСАНИЕ: команда genrsa генерирует закрытый ключ RSA». openssl.org/docs/apps/genrsa.html
Despertar,

124
@jaime, потому что это не так - genrsa генерирует только закрытый ключ, открытый ключ не сохраняется. Однако, если у вас есть закрытый ключ, вы можете вычислить (извлечь) открытый ключ из него - это то, что делает 2-я команда выше. Он вычисляет, а не извлекает открытый ключ.
Steveayre

13
@steveayre Насколько я понимаю, ключи RSA были просто двумя показателями ( eи dв обычной литературе). Ни один из них не является математически частным или общедоступным, это ярлыки, которые произвольно назначаются при создании. Их можно так же легко назначить в обратном порядке. Создание одного из другого является эквивалентной проблемой. .pemФормат содержит целую кучу информации, в том числе обоих показателей, так как ключи, правильно?
Линкс

13
@steveayre в основном неправильно. Компоненты открытого ключа RSA (n, e) ДОЛЖНЫ генерироваться и встраиваться в файл закрытого ключа RSA, созданный с помощью openssl genrsaкоманды. Отдельный файл открытого ключа не создается на том же этапе. Чтобы извлечь открытый ключ из файла закрытого ключа в отдельный файл открытого ключа, используйте вашу openssl rsa -in private.pem -pubout -out public.pemкоманду. Когда вы создаете открытый ключ таким образом, он извлекается из файла закрытого ключа, а не вычисляется. Смотрите мой ответ ниже для более подробной информации.
голем

273

Люди ищут SSH открытый ключ ...

Если вы хотите извлечь открытый ключ для использования с OpenSSH, вам нужно будет получить открытый ключ немного по-другому

$ ssh-keygen -y -f mykey.pem > mykey.pub

Этот формат открытого ключа совместим с OpenSSH. Добавьте открытый ключ к, remote:~/.ssh/authorized_keysи вам будет хорошо


документы из SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Эта опция будет читать приватный файл формата OpenSSH и печатать открытый ключ OpenSSH на стандартный вывод.


3
Это работает как шарм! Он генерирует формат, который принимает Github! Github не принимает формат PEM. Предложенный предыдущий ответ openssl rsa -in key.pem -pubout -out pubkey.pemне был принят, поскольку очевидно, что результатом является открытый ключ формата pem. Итак, я получил эту ошибку: «Ключ недействителен. Он должен начинаться с« ssh-rsa »или« ssh-dss ». Проверьте, что вы копируете открытую половину ключа». Однако ssh-keygen -y [-f input_keyfile] генерирует правильный формат, который принимает Github.
Деви

71

В большинстве программ, которые генерируют закрытые ключи RSA, включая openssl, закрытый ключ представляется как объект RSAPrivatekey PKCS # 1 или какой-либо его вариант:

A.1.2 Синтаксис закрытого ключа RSA


Закрытый ключ RSA должен быть представлен с помощью типа ASN.1 RSAPrivateKey:

  RSAPrivateKey ::= SEQUENCE {
      version           Version,
      modulus           INTEGER,  -- n
      publicExponent    INTEGER,  -- e
      privateExponent   INTEGER,  -- d
      prime1            INTEGER,  -- p
      prime2            INTEGER,  -- q
      exponent1         INTEGER,  -- d mod (p-1)
      exponent2         INTEGER,  -- d mod (q-1)
      coefficient       INTEGER,  -- (inverse of q) mod p
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }

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


Вы имеете в виду, что с учетом закрытого ключа математически возможно генерировать открытый ключ? Разве сила RSA не в том, что в вычислительном отношении невозможно сгенерировать один ключ с учетом другого?
Raam

30
@Raam: Нет, сила RSA в том, что невозможно сгенерировать закрытый ключ из открытого. Генерировать публичную форму, частную, тривиально.
Президент Джеймс К. Полк

@GregS, почему? Ключ состоит из модуля и показателя степени. Если другой показатель степени можно рассчитать из этих двух чисел, RSA будет легко взломан. Таким образом, закрытый ключ OpenSSL содержит больше, чем показатель степени и модуль?
Кальмарий

1
@ Калмариус: Кто сказал, что ключ состоит из модуля и показателя степени? Это был бы минимальный закрытый ключ, но обычно закрытый ключ включает в себя другие компоненты, такие как основные факторы. Прочитайте ответ для деталей.
Президент Джеймс К. Полк

1
@JamesKPolk Это не обязательно так. Если открытый показатель большой (то есть имеет те же свойства, что и частный показатель), то открытый ключ может быть невозможно восстановить. Большинство библиотек не поддерживают это, но криптосистема RSA определенно не требует, чтобы вы восстанавливали открытый ключ из закрытого ключа.
Maarten Bodewes

34

Мой ответ ниже немного длинен, но, надеюсь, он содержит некоторые детали, которые отсутствуют в предыдущих ответах. Я начну с некоторых связанных утверждений и, наконец, отвечу на первоначальный вопрос.

Чтобы зашифровать что-либо с помощью алгоритма RSA, вам понадобится пара модулей экспоненты и модуля шифрования (общедоступная) (n, e). Это твой открытый ключ. Чтобы расшифровать что-либо с помощью алгоритма RSA, вам нужна пара модулей экспонент (n, d) для модуля и дешифрования (приватная). Это твой закрытый ключ.

Чтобы зашифровать что-либо с помощью открытого ключа RSA, вы рассматриваете свой открытый текст как число и повышаете его до степени e modulus n:

ciphertext = ( plaintext^e ) mod n

Чтобы расшифровать что-либо с помощью закрытого ключа RSA, вы рассматриваете свой зашифрованный текст как число и повышаете его до степени d модуля n:

plaintext = ( ciphertext^d ) mod n

Чтобы сгенерировать закрытый (d, n) ключ с помощью openssl, вы можете использовать следующую команду:

openssl genrsa -out private.pem 1024

Чтобы сгенерировать открытый (e, n) ключ из закрытого ключа с помощью openssl, вы можете использовать следующую команду:

openssl rsa -in private.pem -out public.pem -pubout

Чтобы проанализировать содержимое частного RSA-ключа private.pem, сгенерированного вышеуказанной командой openssl, выполните следующее (выходные данные урезаны до меток здесь):

openssl rsa -in private.pem -text -noout | less

modulus         - n
privateExponent - d
publicExponent  - e
prime1          - p
prime2          - q
exponent1       - d mod (p-1)
exponent2       - d mod (q-1)
coefficient     - (q^-1) mod p

Разве закрытый ключ не должен состоять только из (n, d) пары? Почему есть 6 дополнительных компонентов? Он содержит e (открытый показатель), так что открытый ключ RSA можно сгенерировать / извлечь / извлечь из частного ключа RSA private.pem. Остальные 5 компонентов предназначены для ускорения процесса расшифровки. Оказывается, что путем предварительного вычисления и сохранения этих 5 значений можно ускорить дешифрование RSA в 4 раза. Дешифрование будет работать без этих 5 компонентов, но это можно сделать быстрее, если они вам пригодятся. Алгоритм ускорения основан на китайской теореме об остатках .

Да, закрытый ключ private.pem RSA на самом деле содержит все эти 8 значений; ни один из них не генерируется на лету при запуске предыдущей команды. Попробуйте выполнить следующие команды и сравните вывод:

# Convert the key from PEM to DER (binary) format
openssl rsa -in private.pem -outform der -out private.der

# Print private.der private key contents as binary stream
xxd -p private.der

# Now compare the output of the above command with output 
# of the earlier openssl command that outputs private key
# components. If you stare at both outputs long enough
# you should be able to confirm that all components are
# indeed lurking somewhere in the binary stream
openssl rsa -in private.pem -text -noout | less

Эта структура закрытого ключа RSA рекомендуется PKCS # 1 v1.5 в качестве альтернативного ( второго ) представления. Стандарт PKCS # 1 v2.0 исключает показатели e и d из альтернативного представления. PKCS # 1 v2.1 и v2.2 предлагают дальнейшие изменения в альтернативном представлении путем необязательного включения большего количества компонентов, связанных с CRT.

Чтобы увидеть содержимое публичного RSA-ключа public.pem, выполните следующее (выходные данные обрезаны до меток здесь):

openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

Здесь нет сюрпризов. Это просто (n, e) пара, как и обещано.

Теперь, наконец, отвечаем на первоначальный вопрос: как было показано выше, закрытый ключ RSA, сгенерированный с использованием openssl, содержит компоненты открытого и закрытого ключей и некоторые другие. Когда вы генерируете / извлекаете / извлекаете открытый ключ из закрытого ключа, openssl копирует два из этих компонентов (e, n) в отдельный файл, который становится вашим открытым ключом.


Вы написали «Создать открытый (d, n) ключ из закрытого ключа ...». Разве это не должно быть "(е, п)"? Спасибо за отличный ответ!
восхитительно

Вы сравниваете (внешний) «синтаксис» в v1.5 с семантикой в ​​более поздних версиях; проверьте 2.0 # 11.1.2 и 2.1 и 2.2 # A.1.2, и вы увидите, что n, e, d все еще присутствует. (Как уже отмечался ответ Джеймса Полка.)
dave_thompson_085

1
удивительное объяснение. Спасибо
Франциско Альберт

1
Кажется, что публичный показатель eвсегда равен 65537 0x010001. Вероятно, это является дефактом для выбора публичного показателя, и, вероятно, именно поэтому на странице руководства, и почти в каждом месте genrsa, объясняется как to generate the private key. Публичный вид довольно очевиден.
шампунь

Могу ли я вычислить (n, e) только из (n, d)?
Flyq

21

Открытый ключ не хранится в файле PEM, как думают некоторые. В файле закрытого ключа присутствует следующая структура DER:

openssl rsa -text -in mykey.pem

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Таким образом, имеется достаточно данных для расчета открытого ключа (модуль и открытый показатель), что openssl rsa -in mykey.pem -puboutделает


Я вижу, что открытый ключ там не хранится, хотя выводится так же, как и закрытый ключ, но я также не вижу приватный ключ, хранящийся там ?! Тем не менее, если я cat pem файл, я вижу, что он говорит, закрытый ключ и некоторые ascii.
Барлоп

2
Закрытый ключ также является производным, посмотрите на поле privateExponent. Вы можете увидеть поля, используя openssl rsa -text -in mykey.pem
Uxio

2
Открытый ключ фактически хранится в pem, потому что pem также включает в себя e и d, то есть открытый ключ. В отличие от дискретных лог-алгоритмов открытый ключ rsa не может быть рассчитан только из личного ключа (d, n). Он существует только потому, что спецификации rsa указывают на то, что он должен храниться с закрытым ключом и другой информацией.
Майкл Чурдакис

1
Да, этот ответ во всех намерениях и целях НЕПРАВИЛЬНЫЙ . Здесь есть и открытый показатель, и модуль, поэтому открытый ключ обязательно присутствует. Там нет необходимости в открытом показателе, кроме как легко получить открытый ключ для него без каких-либо расчетов .
Мартен Бодевес

1
@MaartenBodewes: ответ правильный. То, что указано, берется из соответствующего RFC в качестве значений, хранящихся для ключа PRIVATE. То, что два значения также / используются только для шифрования с открытым ключом, не меняет того, что это данные закрытого ключа. Я изучил все это за последние два дня, не задавая вопросы, а изучая и читая соответствующий стандарт. Теперь я понимаю все о ASN.1, DER, PEM и RSA (ну, возможно, не ВСЕ о RSA).
AlastairG

8

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

openssl rsa -in mykey.pem -pubout > mykey.pub

надеюсь, вы получите его для получения дополнительной информации, проверьте это


6

Во-первых, быстрый обзор генерации ключей RSA.

  1. Случайно выберите два случайных вероятных простых числа подходящего размера (p и q).
  2. Умножьте два простых числа вместе, чтобы получить модуль (n).
  3. Выберите публичный показатель (е).
  4. Сделайте некоторую математику с простыми числами и открытым показателем, чтобы получить частный показатель (d).

Открытый ключ состоит из модуля и открытого показателя.

Минимальный закрытый ключ состоит из модуля и частного показателя. Не существует надежного в вычислительном отношении способа безошибочного перехода от известного модуля и частного показателя к соответствующему общему показателю.

Однако:

  1. Практические форматы закрытых ключей почти всегда хранят больше n и d.
  2. Обычно он выбирается не случайно, используется одно из нескольких известных значений. Если e является одним из общеизвестных значений и вы знаете d, тогда было бы легко определить e методом проб и ошибок.

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


1
Use the following commands:

1. openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

Loading 'screen' into random state - done
Generating a 2048 bit RSA private key
.............+++
..................................................................................................................................................................+++
writing new private key to 'mycert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

2. If you check there will be a file created by the name : mycert.pem

3. openssl rsa -in mycert.pem -pubout > mykey.txt
writing RSA key

4. If you check the same file location a new public key : mykey.txt will be created.

1
Это глупо; нет необходимости прилагать дополнительные усилия для создания бесполезного сертификата, когда все, что вам нужно, это пара ключей. Для некоторого другого Q, где вы хотите сертификат, это может быть ответом.
dave_thompson_085
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.