Używać klucza prywatnego RSA do generowania klucza publicznego?


394

Naprawdę nie rozumiem tego:

zgodnie z: http://www.madboa.com/geek/openssl/#key-rsa , Możesz wygenerować klucz publiczny z klucza prywatnego.

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

Początkowo myślałem, że są one generowane razem w parze. Czy klucz prywatny RSA zawiera sumę? lub klucz publiczny?


1
Do każdego używającego rsa i openssl i chcącego zaszyfrować duży plik, taki jak 5 Kbyte. pamiętaj, że klucz publiczny powinien być proporcjonalny lub większy w stosunku do tego, co chcesz zaszyfrować, w przeciwnym razie otrzymasz „błąd pliku za duży do zaszyfrowania”. Podsumowuję, że generujesz dość duży i poważny klucz prywatny, a następnie tworzysz klucze prywatne, dzięki czemu masz dużo danych do pracy. Powiedziałem komuś, kogo znam w openssl, o usterce i że powinni po prostu zrobić sobie z tym pętlę, w przeciwnym razie poświęcisz dużo czasu na zastanowienie się, dlaczego narzeka na rozmiar.
Kent Hansen

10
Problem, który opisuje Kent Hansen, wynika z używania RSA bezpośrednio na danych w postaci zwykłego tekstu, czego nigdy nie należy robić ze względów bezpieczeństwa. Zamiast tego użyj dobrze przeanalizowanego hybrydowego schematu szyfrowania, takiego jak RSA-KEM ( tools.ietf.org/html/rfc5990#appendix-A ), z uwierzytelnionym symetrycznym schematem szyfrowania, takim jak szyfrowanie-następnie-HMAC zastosowanym do danych.
Daira Hopwood



Odpowiedź SteffenUllricha w tym linku wyjaśnia, dlaczego: security.stackexchange.com/questions/172274/…
bearzyj

Odpowiedzi:


577
openssl genrsa -out mykey.pem 1024

wyprodukuje parę kluczy publiczny - prywatny. Para jest przechowywana w wygenerowanym mykey.pempliku.

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

wyodrębni klucz publiczny i wydrukuje go. Oto link do strony, która lepiej to opisuje.

EDYCJA: Sprawdź sekcję przykładów tutaj . Aby wydrukować tylko część publiczną klucza prywatnego:

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

Aby uzyskać użyteczny klucz publiczny do celów SSH, użyj ssh-keygen :

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

50
mylące jest to, że wszyscy w tutorialach na całym świecie mówią, że za pomocą polecenia openssl genrsa wygenerujesz PRYWATNY KLUCZ, ponieważ zapominają, że generuje również KLUCZ PUBLICZNY
Jaime Hablutzel

15
@jaime, czy naprawdę możesz ich winić? Oficjalna dokumentacja absolutnie nic nie mówi o kluczu publicznym. „OPIS: Komenda genrsa generuje klucz prywatny RSA.” openssl.org/docs/apps/genrsa.html
Despertar

124
@jaime, To dlatego, że tak nie jest - genrsa generuje tylko klucz prywatny, klucz publiczny nie jest przechowywany. Jeśli jednak masz klucz prywatny, możesz obliczyć (wyprowadzić) klucz publiczny z tego - co właśnie robi powyższe drugie polecenie. Oblicza, a nie wyodrębnia klucz publiczny.
steveayre

13
@steveayre Rozumiałem, że klucze RSA były po prostu dwoma wykładnikami ( ei dwe wspólnej literaturze). Żadne z nich nie jest matematycznie prywatne ani publiczne, są to etykiety, które są arbitralnie przypisywane podczas tworzenia. Można je równie łatwo przypisać do tyłu. Generowanie jednego z drugiego jest równoważnym problemem. .pemFormat zawiera całą masę informacji, w tym zarówno wykładników, a więc zarówno kluczy, prawda?
lynks,

13
@steveayre jest w większości błędny. Publiczne komponenty klucza RSA (n, e) są generowane za pomocą i są osadzone w prywatnym pliku kluczy RSA utworzonym za pomocą openssl genrsapolecenia. Osobny plik klucza publicznego nie jest tworzony na tym samym etapie. Aby wyodrębnić klucz publiczny z pliku klucza prywatnego do osobnego pliku klucza publicznego, użyj openssl rsa -in private.pem -pubout -out public.pempolecenia. Utworzony w ten sposób klucz publiczny jest wyodrębniany z pliku klucza prywatnego, nie obliczany. Zobacz moją odpowiedź poniżej, aby uzyskać więcej informacji.
golem

273

Ludzie szukający klucza publicznego SSH ...

Jeśli chcesz wyodrębnić klucz publiczny do użytku z OpenSSH, musisz uzyskać klucz publiczny nieco inaczej

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

Ten format klucza publicznego jest zgodny z OpenSSH. Dołącz klucz publiczny do, remote:~/.ssh/authorized_keysa będziesz gotowy


dokumenty z SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Ta opcja odczytuje prywatny plik w formacie OpenSSH i wydrukuje klucz publiczny OpenSSH na standardowe wyjście.


3
To działa jak urok! Generuje format, który przyjmuje Github! Github nie przyjmuje openssl rsa -in key.pem -pubout -out pubkey.pemformatu PEM. Poprzednia sugerowana odpowiedź nie została zaakceptowana, ponieważ najwyraźniej wynikiem tego jest klucz publiczny w formacie pem. Tak więc otrzymałem błąd: „Klucz jest nieprawidłowy. Musi zaczynać się od„ ssh-rsa ”lub„ ssh-dss ”. Sprawdź, czy kopiujesz publiczną połowę klucza”. ssh-keygen -y [-f input_keyfile] Generuje jednak poprawny format, który przyjmuje Github.
Devy,

71

W większości programów generujących klucze prywatne RSA, w tym klucze opensl, klucz prywatny jest reprezentowany jako obiekt RSAPrivatekey PKCS # 1 lub jego wariant:

A.1.2 Składnia klucza prywatnego RSA

Klucz prywatny RSA powinien być reprezentowany za pomocą
RSAPrivateKey typu 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
  }

Jak widać, ten format ma wiele pól, w tym moduł i wykładnik publiczny, a zatem jest ścisłym nadzorem informacji w kluczu publicznym RSA .


Czy masz na myśli to, że biorąc pod uwagę klucz prywatny, matematycznie możliwe jest wygenerowanie klucza publicznego? Czy siła RSA nie polega na tym, że wygenerowanie jednego klucza jest niewykonalne obliczeniowo względem drugiego?
Raam,

30
@Ram: Nie, siła RSA polega na tym, że generowanie klucza prywatnego z publicznego jest niemożliwe. Generowanie formy publicznej prywatnej jest banalne.
Prezydent James K. Polk

@GregS, dlaczego? Klucz składa się z modułu i wykładnika potęgi. Jeśli drugi wykładnik można obliczyć z tych dwóch liczb, RSA łatwo by się złamało. Czy zatem prywatny klucz OpenSSL zawiera więcej niż wykładnik i moduł?
Calmarius

1
@Calmarius: Kto mówi, że klucz składa się z modułu i wykładnika? Byłby to minimalny klucz prywatny, ale zwykle klucz prywatny zawiera inne składniki, takie jak czynniki pierwsze. Przeczytaj odpowiedź, aby poznać szczegóły.
Prezydent James K. Polk,

1
@JamesKPolk To niekoniecznie prawda. Jeśli wykładnik publiczny jest duży (tzn. Ma takie same właściwości jak wykładnik prywatny), klucz publiczny może być niemożliwy do odtworzenia. Większość bibliotek nie obsługuje tego, ale kryptosystem RSA z pewnością nie wymaga rekonstrukcji klucza publicznego z klucza prywatnego.
Maarten Bodewes

34

Moja odpowiedź poniżej jest nieco długa, ale mam nadzieję, że zawiera pewne szczegóły, których brakuje w poprzednich odpowiedziach. Zacznę od kilku powiązanych ze sobą stwierdzeń i na koniec odpowiem na wstępne pytanie.

Aby zaszyfrować coś przy użyciu algorytmu RSA, potrzebujesz modułu i pary wykładników szyfrowania (publicznego) (n, e). To twój klucz publiczny. Aby odszyfrować coś przy użyciu algorytmu RSA, potrzebujesz modułu i pary wykładników (prywatnych) wykładników (n, d). To twój klucz prywatny.

Aby zaszyfrować coś przy użyciu klucza publicznego RSA, traktujesz swój tekst jawny jako liczbę i podnosisz go do potęgi modułu e:

ciphertext = ( plaintext^e ) mod n

Aby odszyfrować coś za pomocą klucza prywatnego RSA, traktujesz swój tekst zaszyfrowany jako liczbę i podnosisz go do potęgi modułu d:

plaintext = ( ciphertext^d ) mod n

Aby wygenerować klucz prywatny (d, n) za pomocą openssl, możesz użyć następującego polecenia:

openssl genrsa -out private.pem 1024

Aby wygenerować klucz publiczny (e, n) z klucza prywatnego za pomocą openssl, możesz użyć następującego polecenia:

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

Aby przeanalizować zawartość prywatnego.pem prywatnego klucza RSA wygenerowanego przez powyższe polecenie openssl, uruchom następujące polecenie (dane wyjściowe są obcięte tutaj do etykiet):

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

Czy klucz prywatny nie powinien składać się tylko z pary (n, d)? Dlaczego jest 6 dodatkowych komponentów? Zawiera e (wykładnik publiczny), dzięki czemu publiczny klucz RSA może zostać wygenerowany / wyodrębniony / wyprowadzony z prywatnego.pem prywatnego klucza RSA. Pozostałe 5 elementów ma przyspieszyć proces odszyfrowywania. Okazuje się, że przez wstępne obliczenie i przechowanie tych 5 wartości można przyspieszyć odszyfrowanie RSA czterokrotnie. Odszyfrowanie będzie działać bez tych 5 składników, ale można to zrobić szybciej, jeśli masz je pod ręką. Algorytm przyspieszenia oparty jest na chińskim twierdzeniu o pozostałej liczbie .

Tak, private.pem Klucz prywatny RSA zawiera wszystkie te 8 wartości; żadne z nich nie jest generowane w locie po uruchomieniu poprzedniego polecenia. Spróbuj uruchomić następujące polecenia i porównaj dane wyjściowe:

# 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

Ta struktura klucza prywatnego RSA jest zalecana przez PKCS # 1 v1.5 jako alternatywna ( druga ) reprezentacja. Standard PKCS # 1 v2.0 całkowicie wyklucza wykładniki e i d z alternatywnej reprezentacji. PKCS # 1 v2.1 i v2.2 proponują dalsze zmiany w alternatywnej reprezentacji, opcjonalnie włączając więcej komponentów związanych z CRT.

Aby zobaczyć zawartość publicznego.pem publicznego klucza RSA, uruchom następujące polecenie (dane wyjściowe są obcięte do etykiet tutaj):

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

Modulus             - n
Exponent (public)   - e

Żadnych niespodzianek. To tylko (n, e) para, jak obiecano.

Teraz w końcu odpowiadając na początkowe pytanie: Jak pokazano powyżej, prywatny klucz RSA wygenerowany za pomocą openssl zawiera składniki zarówno klucza publicznego, jak i prywatnego i kilka innych. Kiedy generujesz / wyodrębniasz / wyprowadzasz klucz publiczny z klucza prywatnego, openssl kopiuje dwa z tych składników (e, n) do osobnego pliku, który staje się twoim kluczem publicznym.


napisałeś „Aby wygenerować klucz publiczny (d, n) z klucza prywatnego ...”. Czy nie powinno to być „(e, n)”? Dziękuję za wspaniałą odpowiedź!
elaktyczny

Porównujesz (zewnętrzną) „składnię” w wersji 1.5 z semantyką w późniejszych wersjach; zaznacz 2.0 # 11.1.2 i 2.1 oraz 2.2 # A.1.2, a zobaczysz n, e, d nadal obecne. (Jak już zauważyła odpowiedź Jamesa Polka.)
dave_thompson_085

1
niesamowite wyjaśnienie. Dzięki
Francisco Albert

1
Wydaje się, że wykładnik publiczny ewynosi zawsze 65537 0x010001. Prawdopodobnie jest to wadą przy wyborze wykładnika publicznego i prawdopodobnie dlatego na stronie podręcznika i prawie wszędzie genrsajest wyjaśnione jako to generate the private key. Publiczny jest dość oczywisty.
szampon

Czy mogę obliczyć (n, e) tylko z (n, d)?
Flyq

21

Klucz publiczny nie jest przechowywany w pliku PEM, jak niektórzy sądzą. Następująca struktura DER znajduje się w pliku klucza prywatnego:

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
}

Jest więc wystarczająco dużo danych, aby obliczyć klucz publiczny (moduł i wykładnik publiczny), co właśnie openssl rsa -in mykey.pem -puboutrobi


Widzę, że klucz publiczny nie jest tam przechowywany, chociaż można go wyprowadzić tak jak klucz prywatny, ale nie widzę też, aby klucz prywatny był tam przechowywany ?! ale jeśli sonduję plik pem, widzę, że zawiera klucz prywatny i niektóre ascii.
barlop

2
Klucz prywatny jest również wyprowadzany, spójrz na pole privateExponent. Możesz zobaczyć pola używając openssl rsa -text -in mykey.pem
Uxio

2
Klucz publiczny jest faktycznie przechowywany w pem, ponieważ pem zawiera również e id, to znaczy klucz publiczny. W przeciwieństwie do dyskretnych algorytmów dziennika, klucza publicznego rsa nie można obliczyć na podstawie klucza prywatnego (d, n). Jest tak tylko dlatego, że specyfikacje rsa wskazują, aby przechowywać go z kluczem prywatnym i innymi informacjami.
Michael Chourdakis,

1
Tak, ta odpowiedź jest w całej intencji i jest ZŁA . Występuje zarówno wykładnik publiczny, jak i moduł, więc klucz publiczny jest z pewnością obecny. Publiczny wykładnik wykładowy nie jest potrzebny poza łatwym odzyskaniem klucza publicznego bez żadnych obliczeń .
Maarten Bodewes

1
@MaartenBodewes: Odpowiedź jest prawidłowa. To, co jest cytowane, pochodzi z odpowiedniego RFC jako wartości przechowywane dla klucza PRYWATNEGO. To, że dwie wartości są również używane tylko do szyfrowania klucza publicznego, nie zmienia faktu, że są to dane klucza prywatnego. Nauczyłem się tych wszystkich rzeczy w ciągu ostatnich dwóch dni, nie zadając pytań, ale patrząc i czytając odpowiedni standard. Teraz rozumiem wszystko na temat ASN.1, DER, PEM i RSA (no może nie WSZYSTKO na temat RSA).
AlastairG

8

tutaj w tym kodzie najpierw tworzymy klucz RSA, który jest prywatny, ale ma również parę swoich kluczy publicznych, więc aby uzyskać rzeczywisty klucz publiczny, po prostu to robimy

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

mam nadzieję, że dostaniesz więcej informacji, sprawdź to


6

Po pierwsze, krótkie podsumowanie generowania kluczy RSA.

  1. Losowo wybierz dwie losowe liczby prawdopodobne o odpowiedniej wielkości (p i q).
  2. Pomnóż dwie liczby pierwsze razem, aby uzyskać moduł (n).
  3. Wybierz wykładnik publiczny (e).
  4. Wykonaj matematykę na liczbach pierwszych i wykładniku publicznym, aby uzyskać wykładnik prywatny (d).

Klucz publiczny składa się z modułu i wykładnika publicznego.

Minimalny klucz prywatny składałby się z modułu i wykładnika prywatnego. Nie ma wykonalnej pod względem obliczeniowym pewnej drogi przejścia od znanego modułu i wykładnika prywatnego do odpowiedniego wykładnika publicznego.

Jednak:

  1. Praktyczne formaty kluczy prywatnych prawie zawsze przechowują więcej niż ni id.
  2. e zwykle nie jest wybierany losowo, używana jest jedna z kilku dobrze znanych wartości. Jeśli e jest jedną z dobrze znanych wartości i wiesz, że d, łatwo byłoby ustalić e metodą prób i błędów.

Tak więc w najbardziej praktycznych implementacjach RSA można uzyskać klucz publiczny z klucza prywatnego. Byłoby możliwe zbudowanie kryptosystemu opartego na RSA tam, gdzie nie byłoby to możliwe, ale nie jest to zrobione.


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
To niemądre; nie trzeba podejmować dodatkowych wysiłków, aby utworzyć bezużyteczny certyfikat, gdy wszystko, czego potrzebujesz, to para kluczy. W przypadku innego Q, w którym chcesz uzyskać certyfikat, może to być odpowiedź.
dave_thompson_085
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.