Використовувати приватний ключ 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 ), із автентифікованою симетричною схемою шифрування, такою як шифрування-потім-HMAC, застосована до даних.
Дайра Хопвуд

Це може допомогти: jason4zhu.blogspot.jp/2014/10/…
Судити


@ Відповідь SteffenUllrich у цьому посиланні пояснює, чому: security.stackexchange.com/questions/172274/…
bearzyj

Відповіді:


577
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, ви генеруєте ПРИЄМНИЙ КЛЮЧ, тому що вони забувають, що він також генерує ПУБЛІЧНИЙ КЛЮЧ
Хайме Хаблутцель

15
@jaime, ти справді можеш їх звинуватити? В офіційній документації абсолютно нічого не сказано про відкритий ключ. "ОПИС: Команда genrsa генерує приватний ключ RSA." openssl.org/docs/apps/genrsa.html
Деспертар

124
@jaime, Це тому, що це не відбувається - genrsa генерує лише приватний ключ, відкритий ключ не зберігається. Однак якщо у вас є приватний ключ, то ви можете обчислити (вивести) відкритий ключ з нього - що і робить друга команда вище. Він обчислює, а не витяги, відкритий ключ.
steveayre

13
@steveayre Я розумів, що ключі RSA були просто двома показниками ( eі dв загальній літературі). Ні один математично не приватний або публічний, це мітки, які довільно присвоюються під час створення. Вони так само легко можуть бути призначені в зворотному порядку. Генерування одного від іншого - рівнозначна проблема. .pemФормат містить цілу купу інформації, в тому числі обох показників, так як ключі, правильно?
рись

13
@steveayre здебільшого помиляється. Загальнодоступні ключові компоненти RSA (n, e) DO генеруються разом із вбудованим файлом ключа 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 для stdout.


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.
Devy

71

У більшості програмного забезпечення, яке генерує приватні ключі RSA, включаючи openssl, приватний ключ представлений у вигляді об'єкта RSAPrivatekey PKCS №1 або якогось його варіанту:

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

Приватний ключ RSA повинен бути представлений разом з
RSAPrivateKey типу ASN.1 :

  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 полягає в тому, що її обчислювально неможливо створити один ключ, враховуючи інший?
Раам

30
@Raam: Ні, сила RSA полягає в тому, що генерувати приватний ключ із загальнодоступного неможливо. Створювати публічну форму приватної - тривіально.
президент Джеймс К. Полк

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

1
@Calmarius: Хто каже, що ключ складається з модуля і експонента? Це був би мінімальний приватний ключ, але зазвичай приватний ключ включає інші компоненти, такі як основні фактори. Прочитайте відповідь для деталей.
Президент Джеймс К. Полк

1
@JamesKPolk Це не обов'язково правда. Якщо загальнодоступний показник великий (тобто має ті ж властивості, що й приватний показник), відкритий ключ може бути неможливий для реконструкції. Більшість бібліотек не підтримують це, але криптосистема RSA, безумовно, не вимагає від вас реконструкції відкритого ключа з приватного ключа.
Maarten Bodewes

34

Моя відповідь нижче трохи тривала, але, сподіваємось, вона містить деякі деталі, яких не вистачає в попередніх відповідях. Почну з деяких пов’язаних тверджень і, нарешті, відповім на початкове запитання.

Щоб зашифрувати щось за допомогою алгоритму RSA, вам потрібні параметри модуля та шифрування (public) (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

Для розсічення вмісту приватного ключа 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.

Щоб побачити вміст загальнодоступного ключа RS.pem RSA, виконайте наступне (висновок, урізаний тут у мітки):

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

Modulus             - n
Exponent (public)   - e

Тут немає сюрпризів. Це просто (п, е) пара, як і обіцяли.

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


Ви написали "Для створення відкритого (d, n) ключа з приватного ключа ...". Чи не повинно бути "(e, 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. Це, мабуть, дефакто для вибору загальнодоступного показника, і це, мабуть, саме тому на сторінці "man", і майже в усіх місцях, де genrsaце пояснено як to generate the private key. Загальнодоступний очевидний.
шампунь

Чи можу я обчислити (n, e) тільки з (n, d)?
Flyq

21

Відкритий ключ не зберігається у файлі PEM, як думають деякі. У файлі приватного ключа присутня така структура DER:

openssl rsa -text -в 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робить


Я бачу, що відкритий ключ там не зберігається, хоча він може бути отриманий, як і приватний ключ, але я також не бачу збережений приватний ключ ?! але якщо я кота pem-файлу, я бачу, що він говорить про приватний ключ і деякі функції ascii.
барлоп

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

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

1
Так, ця відповідь є у всіх намірах і цілях НЕПРАВНИМ . І публічний показник, і модуль є там, тому відкритий ключ, безумовно, присутній. Немає потреби в загальнодоступному експоненті, крім того, щоб легко отримати відкритий ключ для нього без будь-яких розрахунків .
Maarten Bodewes

1
@MaartenBodewes: Відповідь правильна. Те, що цитується, взято з відповідної RFC як значення, збережені для ПРИВАТНОГО ключа. Те, що два значення також / використовуються лише для шифрування відкритого ключа, не змінюється, що це дані приватного ключа. Я дізнався про все це за останні два дні, не задаючи запитання, а переглядаючи та читаючи відповідний стандарт. Зараз я розумію все про 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
Це нерозумно; не потрібно докладати додаткових зусиль, щоб створити марний сертифікат, коли все, що вам потрібно, це ключ. Для деяких інших питань, де ви хочете сертифікувати, це може бути відповіддю.
dave_thompson_085
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.