Использовать закрытый ключ 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.