Gunakan kunci pribadi RSA untuk menghasilkan kunci publik?

394

Saya tidak begitu mengerti yang ini:

menurut: http://www.madboa.com/geek/openssl/#key-rsa , Anda dapat membuat kunci publik dari kunci pribadi.

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

Pemikiran awal saya adalah bahwa keduanya dihasilkan secara berpasangan. Apakah kunci pribadi RSA berisi jumlah? atau kunci publik?

c2h2
sumber
1
Untuk setiap orang menggunakan rsa dan openssl dan ingin mengenkripsi file besar seperti 5 Kbyte. harap ingat bahwa kunci publik harus proporsional atau berukuran lebih besar dari apa yang ingin Anda enkripsi, jika tidak Anda akan mendapatkan "file to big menjadi kesalahan terenkripsi." Saya merangkum bahwa Anda menghasilkan kunci pribadi yang agak besar dan serius dan dari itu membuat kunci pribadi Anda sehingga Anda memiliki banyak data untuk dikerjakan. Saya mengatakan kepada siapa saya tahu di openssl tentang cacat, dan bahwa mereka harus membuatnya loop sendiri jika tidak, Anda akan menggunakan banyak waktu mencari tahu mengapa itu mengeluh tentang ukuran.
Kent Hansen
10
Masalah yang dijelaskan Kent Hansen adalah karena menggunakan RSA secara langsung pada data plaintext, yang tidak boleh dilakukan dalam kasus apa pun karena alasan keamanan. Alih-alih menggunakan skema enkripsi hybrid yang dianalisis dengan baik seperti RSA-KEM ( tools.ietf.org/html/rfc5990#appendix-A ), dengan skema enkripsi simetris terotentikasi seperti enkripsi-kemudian-HMAC yang diterapkan pada data.
Daira Hopwood
Ini dapat membantu: jason4zhu.blogspot.jp/2014/10/...
Judking
@ SteffenUllrich menjawab di tautan ini menjelaskan alasannya: security.stackexchange.com/questions/172274/…
bearzyj

Jawaban:

578
openssl genrsa -out mykey.pem 1024

akan benar-benar menghasilkan pasangan kunci publik-swasta. Pasangan disimpan dalam mykey.pemfile yang dihasilkan .

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

akan mengekstrak kunci publik dan mencetaknya. Berikut ini tautan ke halaman yang menjelaskan hal ini dengan lebih baik.

EDIT: Periksa bagian contoh di sini . Untuk hanya menampilkan bagian publik dari kunci pribadi:

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

Untuk mendapatkan kunci publik yang dapat digunakan untuk keperluan SSH, gunakan ssh-keygen :

ssh-keygen -y -f key.pem > key.pub
Raam
sumber
50
itu membingungkan bagaimana semua orang di tutorial di mana-mana mengatakan bahwa menggunakan perintah openssl genrsa Anda akan menghasilkan KUNCI PRIVATE, karena mereka lupa bahwa itu menghasilkan KUNCI PUBLIK juga
Jaime Hablutzel
15
@ James, bisakah Anda benar-benar menyalahkan mereka? Dokumentasi resmi sama sekali tidak mengatakan apa-apa tentang kunci publik. "DESCRIPTION: Perintah genrsa menghasilkan kunci pribadi RSA." openssl.org/docs/apps/genrsa.html
Despertar
124
@jaime, Itu karena tidak - genrsa hanya menghasilkan kunci pribadi, kunci publik tidak disimpan. Namun jika Anda memiliki kunci privat maka Anda dapat menghitung (mendapatkan) kunci publik darinya - yang merupakan perintah kedua di atas. Itu menghitung, bukan mengekstrak, kunci publik.
steveayre
13
@steveayre Ini adalah pemahaman saya bahwa kunci RSA hanyalah dua eksponen ( edan ddalam literatur umum). Tidak satu pun secara matematis pribadi atau publik, itu adalah label yang secara sewenang-wenang ditetapkan pada saat penciptaan. Mereka bisa dengan mudah ditugaskan secara terbalik. Menghasilkan satu dari yang lain adalah masalah yang setara. The .pemFormat berisi sejumlah besar informasi, termasuk kedua eksponen, dan kedua tombol, kan?
lynks
13
@steveayre sebagian besar salah. Komponen kunci RSA publik (n, e) DO dibuat dengan dan disematkan ke file kunci RSA pribadi yang dibuat dengan openssl genrsaperintah. File kunci publik yang terpisah tidak dibuat pada langkah yang sama. Untuk mengekstrak kunci publik dari file kunci pribadi ke file kunci publik yang terpisah, Anda menggunakan openssl rsa -in private.pem -pubout -out public.pemperintah Anda . Ketika Anda menghasilkan kunci publik dengan cara ini, itu diekstraksi dari file kunci pribadi, tidak dihitung. Lihat jawaban saya di bawah ini untuk lebih jelasnya.
golem
273

Orang yang mencari kunci publik SSH ...

Jika Anda ingin mengekstrak kunci publik untuk digunakan dengan OpenSSH, Anda perlu mendapatkan kunci publik sedikit berbeda

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

Format kunci publik ini kompatibel dengan OpenSSH. Tambahkan kunci publik untuk remote:~/.ssh/authorized_keysdan Anda akan baik untuk pergi


dokumen dari SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Opsi ini akan membaca file format OpenSSH pribadi dan mencetak kunci publik OpenSSH ke stdout.

Terima kasih
sumber
3
Ini bekerja seperti pesona! Ini menghasilkan format yang diambil Github! Github tidak mengambil format PEM. Jawaban sebelumnya yang disarankan openssl rsa -in key.pem -pubout -out pubkey.pemtidak diterima karena ternyata hasilnya adalah kunci publik format pem. Jadi saya mendapatkan kesalahan ini: "Kunci tidak valid. Ini harus dimulai dengan 'ssh-rsa' atau 'ssh-dss'. Periksa apakah Anda menyalin bagian publik dari kunci". Namun ssh-keygen -y [-f input_keyfile] menghasilkan format yang benar yang diambil Github.
Devy
71

Dalam sebagian besar perangkat lunak yang menghasilkan kunci privat RSA, termasuk openssl, kunci privat direpresentasikan sebagai objek RSAPrivatekey PKCS # 1 atau beberapa varian daripadanya:

A.1.2 Sintaks kunci pribadi RSA

Kunci pribadi RSA harus diwakili dengan ASN.1 tipe
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
  }

Seperti yang Anda lihat, format ini memiliki sejumlah bidang termasuk modulus dan eksponen publik dan dengan demikian merupakan superset ketat dari informasi dalam kunci publik RSA .

Presiden James K. Polk
sumber
Apakah maksud Anda bahwa dengan diberikan kunci privat, secara matematis layak untuk menghasilkan kunci publik? Bukankah kekuatan RSA adalah fakta bahwa secara komputasi tidak mungkin untuk menghasilkan satu kunci diberikan yang lain?
Raam
30
@ Raam: Tidak, kekuatan RSA adalah bahwa tidak mungkin menghasilkan kunci pribadi dari publik. Hasilkan bentuk publik, pribadi itu sepele.
Presiden James K. Polk
@Reg, Mengapa? Kunci terdiri dari modulus dan eksponen. Jika eksponen lain dapat dihitung dari dua angka ini, RSA akan mudah retak. Jadi, apakah kunci privat OpenSSL mengandung lebih dari eksponen dan modulus?
Calmarius
1
@Calmarius: Siapa bilang kunci terdiri dari modulus dan eksponen? Itu akan menjadi kunci privat minimal, tetapi biasanya kunci privat mencakup komponen lain seperti faktor prima. Baca jawaban untuk detailnya.
Presiden James K. Polk
1
@ JamesKPolk Itu belum tentu benar. Jika eksponen publik besar (yaitu memiliki sifat yang sama dengan eksponen swasta) maka kunci publik mungkin mustahil untuk direkonstruksi. Sebagian besar perpustakaan tidak akan mendukung ini, tetapi cryptosystem RSA jelas tidak mengharuskan Anda untuk merekonstruksi kunci publik dari kunci pribadi.
Maarten Bodewes
34

Jawaban saya di bawah ini agak panjang, tapi mudah-mudahan ini memberikan beberapa detail yang hilang dalam jawaban sebelumnya. Saya akan mulai dengan beberapa pernyataan terkait dan akhirnya menjawab pertanyaan awal.

Untuk mengenkripsi sesuatu menggunakan algoritma RSA Anda memerlukan modulus dan enkripsi (publik) pasangan eksponen (n, e). Itu kunci publik Anda. Untuk mendekripsi sesuatu menggunakan algoritma RSA Anda memerlukan pasangan eksponen modulus dan dekripsi (pribadi) (n, d). Itu kunci pribadi Anda.

Untuk mengenkripsi sesuatu menggunakan kunci publik RSA, Anda memperlakukan plaintext Anda sebagai angka dan menaikkannya menjadi kekuatan modul:

ciphertext = ( plaintext^e ) mod n

Untuk mendekripsi sesuatu menggunakan kunci privat RSA, Anda memperlakukan ciphertext Anda sebagai angka dan menaikkannya dengan kekuatan modulus:

plaintext = ( ciphertext^d ) mod n

Untuk menghasilkan kunci pribadi (d, n) menggunakan openssl Anda dapat menggunakan perintah berikut:

openssl genrsa -out private.pem 1024

Untuk menghasilkan kunci publik (e, n) dari kunci pribadi menggunakan openssl Anda dapat menggunakan perintah berikut:

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

Untuk membedah konten kunci RSA private.pem pribadi yang dihasilkan oleh perintah openssl di atas, jalankan perintah berikut (output terpotong ke label di sini):

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

Bukankah kunci pribadi hanya terdiri dari (n, d) pasangan? Mengapa ada 6 komponen tambahan? Ini berisi e (eksponen publik) sehingga kunci RSA publik dapat dihasilkan / diekstraksi / berasal dari kunci RSA pribadi private.pem. Sisanya 5 komponen ada untuk mempercepat proses dekripsi. Ternyata dengan melakukan pra-komputasi dan menyimpan 5 nilai tersebut, dimungkinkan untuk mempercepat dekripsi RSA dengan faktor 4. Dekripsi akan bekerja tanpa 5 komponen itu, tetapi dapat dilakukan lebih cepat jika Anda memilikinya. Algoritma percepatan didasarkan pada Teorema Sisa Cina .

Ya, private.pem Kunci privat RSA sebenarnya berisi ke-8 nilai tersebut; tidak satu pun dari mereka dihasilkan dengan cepat ketika Anda menjalankan perintah sebelumnya. Coba jalankan perintah berikut dan bandingkan output:

# 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

Struktur kunci pribadi RSA ini direkomendasikan oleh PKCS # 1 v1.5 sebagai representasi alternatif ( kedua ). Standar PKCS # 1 v2.0 mengecualikan eksponen e dan d dari representasi alternatif secara keseluruhan. PKCS # 1 v2.1 dan v2.2 mengusulkan perubahan lebih lanjut pada representasi alternatif, dengan secara opsional memasukkan lebih banyak komponen yang terkait dengan CRT.

Untuk melihat konten kunci RSA publik.pem publik jalankan yang berikut (output terpotong ke label di sini):

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

Modulus             - n
Exponent (public)   - e

Tidak ada kejutan di sini. Itu hanya (n, e) pasangan, seperti yang dijanjikan.

Sekarang akhirnya menjawab pertanyaan awal: Seperti yang ditunjukkan di atas kunci RSA pribadi yang dihasilkan menggunakan openssl berisi komponen kunci publik dan pribadi dan beberapa lagi. Ketika Anda membuat / mengekstrak / mendapatkan kunci publik dari kunci privat, membuka salinan dua komponen tersebut (e, n) ke file terpisah yang menjadi kunci publik Anda.

golem
sumber
Anda menulis "Untuk menghasilkan kunci publik (d, n) dari kunci pribadi ...". Bukankah seharusnya "(e, n)"? Terima kasih atas jawaban yang bagus!
elaktik
Anda sedang membandingkan (eksternal) 'sintaks' di v1.5 dengan semantik di versi yang lebih baru; periksa 2.0 # 11.1.2 dan 2.1 dan 2.2 # A.1.2 dan Anda akan melihat n, e, d masih ada. (Seperti jawaban James Polk telah dicatat.)
dave_thompson_085
1
penjelasan yang luar biasa. Terima kasih
Francisco Albert
1
Tampaknya eksponen publik eselalu 65537 0x010001. Ini mungkin defacto untuk memilih eksponen publik dan ini mungkin mengapa di halaman manual, dan hampir setiap tempat genrsadijelaskan sebagai to generate the private key. Yang umum agak jelas.
shampo
Bisakah saya menghitung (n, e) hanya dari (n, d)?
Flyq
21

Kunci Publik tidak disimpan dalam file PEM seperti yang dipikirkan sebagian orang. Struktur DER berikut ada pada File Kunci Pribadi:

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
}

Jadi ada cukup data untuk menghitung Kunci Publik (modulus dan eksponen publik), yang memang openssl rsa -in mykey.pem -puboutberfungsi

Uxio
sumber
Saya melihat kunci publik tidak disimpan di sana, meskipun dapat diturunkan seperti kunci privat, tetapi saya juga tidak melihat kunci privat tersimpan di sana ?! namun jika saya cat file pem saya melihatnya mengatakan kunci pribadi dan beberapa ascii.
barlop
2
Kunci pribadi juga diturunkan, lihat bidang privateExponent. Anda dapat melihat bidang menggunakan openssl rsa -text -in mykey.pem
Uxio
2
Kunci publik sebenarnya disimpan dalam pem, karena pem juga menyertakan e dan d, yaitu kunci publik. Tidak seperti log algo diskrit, kunci publik rsa tidak dapat dihitung hanya dari kunci privat (d, n). Itu ada hanya karena spesifikasi rsa menunjukkan untuk menyimpannya dengan kunci pribadi dan info lainnya.
Michael Chourdakis
1
Yap, jawaban ini dalam semua maksud dan tujuan SALAH . Baik eksponen publik dan modulus ada di sana, jadi kunci publik pasti ada. Tidak perlu eksponen publik di sana selain untuk dengan mudah mengambil kunci publik untuk itu tanpa perhitungan .
Maarten Bodewes
1
@ MaartenBodewes: Jawabannya benar. Apa yang dikutip diambil dari RFC yang relevan sebagai nilai yang disimpan untuk kunci PRIVATE. Dua nilai tersebut juga / hanya digunakan untuk enkripsi kunci publik tidak mengubah bahwa ini adalah data kunci pribadi. Saya telah mempelajari semua hal ini selama dua hari terakhir, bukan dengan bertanya tetapi dengan melihat dan membaca standar yang relevan. Saya sekarang mengerti semua tentang ASN.1, DER, PEM, dan RSA (mungkin tidak semua tentang RSA).
AlastairG
8

di sini dalam kode ini pertama kita membuat kunci RSA yang bersifat pribadi tetapi memiliki sepasang kunci publik juga jadi untuk mendapatkan kunci publik Anda yang sebenarnya, kami cukup melakukan ini

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

harap Anda mendapatkannya untuk info lebih lanjut, periksa ini

Rdx
sumber
6

Pertama rekap cepat pada generasi kunci RSA.

  1. Pilih secara acak dua bilangan prima kemungkinan acak dengan ukuran yang sesuai (p dan q).
  2. Lipat gandakan kedua bilangan prima untuk menghasilkan modulus (n).
  3. Pilih eksponen publik (e).
  4. Lakukan perhitungan matematika dengan bilangan prima dan eksponen publik untuk menghasilkan eksponen pribadi (d).

Kunci publik terdiri dari modulus dan eksponen publik.

Kunci pribadi minimal akan terdiri dari modulus dan eksponen pribadi. Tidak ada cara pasti yang layak secara komputasi untuk beralih dari modulus yang diketahui dan eksponen swasta ke eksponen publik yang sesuai.

Namun:

  1. Format kunci privat praktis hampir selalu menyimpan lebih dari n dan d.
  2. e biasanya tidak dipilih secara acak, salah satu dari beberapa nilai terkenal digunakan. Jika e adalah salah satu dari nilai-nilai yang terkenal dan Anda tahu d maka akan mudah untuk mengetahui e melalui coba-coba.

Jadi dalam sebagian besar implementasi RSA praktis Anda bisa mendapatkan kunci publik dari kunci pribadi. Mungkin untuk membangun cryptosystem berbasis RSA di mana ini tidak mungkin, tetapi itu bukan hal yang dilakukan.

plugwash
sumber
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.
Ankit Jain
sumber
1
Ini konyol; tidak perlu melakukan upaya ekstra untuk membuat sertifikat tidak berguna ketika semua yang Anda inginkan adalah keypair. Untuk beberapa Q lain di mana Anda menginginkan sertifikat, ini bisa menjadi jawaban.
dave_thompson_085