Bagaimana cara menghasilkan parameter Diffie-Hellman 2048-bit baru dengan Java keytool?

9

Kami bukan ahli yang mencoba - tidak berhasil sejauh ini - untuk memperbarui pengaturan server web kami (JBoss-5.1.0.GA) untuk memenuhi standar Diffie-Hellman. Setelah menjalankan tes di https://weakdh.org/sysadmin.html , kita diberitahu bahwa kita perlu "menghasilkan parameter Diffie-Hellman 2048-bit baru". Di masa lalu, kami telah menghasilkan kunci dengan Java keytool, tetapi kami tidak dapat menemukan informasi tentang menghasilkan parameter Diffie-Hellman 2048-bit baru dengan Java keytool. Adakah yang tahu bagaimana melakukan ini atau dapat mengarahkan kita ke arah yang benar? Terima kasih!

pengguna2072931
sumber

Jawaban:

13

Anda tidak dapat melakukannya dengan keytool. Pertama, sama keytoolsekali tidak mendukung DH. Kedua, keytooltidak menghasilkan parameter sendiri untuk algoritma apa pun, hanya privatekey / keypair. Ketiga, ketika keytoolmenghasilkan keypair itu juga menghasilkan sertifikat yang ditandatangani sendiri (yang kadang - kadang kemudian digantikan oleh sertifikat yang dikeluarkan CA "nyata") dan tidak mungkin untuk menghasilkan sertifikat yang ditandatangani sendiri untuk DH karena DH tidak menandatangani. Anda bisa menulis program Java yang sangat sederhana (sekitar 10 baris) untuk menghasilkan parameter DH. Tapi itu mungkin tidak akan ada gunanya bagimu karena:

Java tidak menerima parameter DHE di sini. JbossWS (server web Jboss, kemudian Wildfly) adalah garpu Tomcat, dan biasanya menggunakan implementasi Java SSL / TLS, JSSE. Melalui Java 7, JSSE menggunakan parameter DHE-nya sendiri yang 768-bit yang sangat lemah. (Kecuali untuk suite EKSPOR di mana JSSE mematuhi persyaratan RFC untuk DH-512, yang benar-benar rusak, tetapi kemudian suite EKSPOR dengan desain benar-benar rusak, dan dinonaktifkan secara default di Java 7 ke atas.) Java 8 JSSE memungkinkan Anda untuk mengontrol ukuran parameter DHE, tetapi bukan nilai sebenarnya.

Opsi Anda (beberapa tumpang tindih) adalah:

Gunakan Java 8. JSSE di Java 8, tetapi tidak lebih awal, standar DHE ke 1024 bit, yang sebagian besar pihak berwenang menganggap cukup kuat meskipun lemahdh.org tidak, dan memungkinkan Anda untuk menentukan lebih lanjut, lihat https://docs.oracle.com /javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys dan untuk latar belakang /programming/30352105/how-to-set-custom-dh-group-in-java -sslengine-untuk-mencegah-logjam-serangan . Perhatikan bahwa jika Anda memiliki klien Java sebelum Java 8, mereka akan gagal jika server menggunakan DHE lebih dari 1024 bit. Saya tidak tahu ada klien lain yang memiliki masalah ini, tetapi uji Anda sebelum melakukan perubahan ini.

Aktifkan ECDHE. JSSE di Java 7 dan yang lebih baru mengimplementasikan ECDHE, yang tidak tunduk pada perhitungan seperti DHE, (biasanya) menggunakan P-256, yang lebih dari cukup kuat. (Meskipun beberapa orang tidak mempercayai salah satu kurva EIST NIST karena NIST secara umum dipengaruhi oleh NSA, meskipun tidak ada sumber terbuka yang saya tahu telah menunjukkan masalah dalam kurva ECC secara khusus.) Java 6 sebenarnya memiliki bagian JSSE untuk ECDHE tetapi ini hanya diaktifkan jika JVM memiliki "penyedia" kripto untuk primitif ECC, yang Java 6 tidak. bcprov - * - jdk15on dari http://www.bouncycastle.org/ adalah penyedia JCE untuk berbagai primitif Java crypto termasuk ECC, jadi jika Anda menambahkan toples ke Anda JRE/lib/extdan menambah org.bouncycastle.jce.provider.BouncyCastleProviderdaftar di JRE/lib/security/java.security(atau melakukan yang sesuaiSecurity.add/insertProvider()suatu tempat di awal kode Anda) Java 6 dapat melakukan ECDHE. Tentu saja apakah Anda harus memiliki Java 6 yang masih digunakan adalah pertanyaan sendiri.

Beberapa tahun yang lalu, dukungan untuk ECDHE di browser dan klien lain tidak bagus, tetapi hari ini AFAIK semua browser terbaru mendukungnya dan lebih memilihnya daripada DHE - yaitu, browser halo mencantumkan suite ECDHE sebelum suite DHE jadi. bahwa jika server mengimplementasikan keduanya harus memilih ECDHE. Klien non-browser mungkin tidak; Tes untuk memastikan.

Nonaktifkan DHE. Anda dapat mengkonfigurasi daftar cipher dalam atribut Connector untuk mengecualikan cipher DHE; sementara Anda melakukannya juga tidak termasuk staticDH dan staticECDH yang tidak berguna, dan (tunggal) DES dan (semua) "EKSPOR" jika ada (Java 6). Ini berarti browser dan klien yang tidak melakukan ECHDE akan terjebak dengan RSA biasa dan tidak ada Forward Secrecy, tetapi setidaknya mereka memiliki kerahasiaan "saat ini". Saya tidak ingat pasti, tapi saya pikir konfigurasi Connector 5.1 masih di suatu tempat $server/deploy/jbossweb/server.xml.

Coba yang asli. Tomcat, yang seperti yang saya katakan JbossWS dimulai, memiliki opsi untuk mengimplementasikan HTTPS (SSL / TLS) menggunakan "asli" alias "APR" yang sebenarnya adalah OpenSSL di dalam daripada JSSE. Saya telah sukses campuran dalam mendapatkan opsi ini untuk bekerja di JbossWS, dan tidak ingat tentang 5.1. Jika JbossWS Anda memiliki opsi TC-native yang bisa diterapkan, dan jika JbossWS Anda dapat menangani konfigurasi parameter DH, maka gunakan openssl untuk menghasilkan parameter DH dan instruksi asli JbossWS untuk mengonfigurasinya.

dave_thompson_085
sumber
Terima kasih untuk informasi yang bagus ini. The jawaban bagi kita akhirnya tidak melibatkan keytool, hanya perubahan ke file server.xml kami, tapi saya akan memeriksa jawaban ini.
user2072931
4

Sebenarnya Anda dapat menentukan Parameter DHE khusus dengan versi Java 8 terbaru . Itu adalah independend dari aplikasi (Asalkan menggunakan implementasi JSSE JSS).

Pertama-tama Anda perlu menentukan ukuran kunci DHE untuk menggunakan ( -Djdk.tls.ephemeralDHKeySize=1024atau -Djdk.tls.ephemeralDHKeySize=2048). Di Server ini akan menggunakan kombinasi generator / prime yang telah ditentukan sebelumnya untuk DHE. Dengan Java 8 hanya 1024 atau 2048 yang dapat digunakan, JDK 9 akan mendukung ukuran yang lebih besar .

Jika Anda ingin memberikan kombinasi yang berbeda, Anda dapat menentukannya di jre / lib / security / Java.security dengan jdk.tls.server.defaultDHEParametersproperti keamanan (sejak 8u51). Dibutuhkan daftar Parameter (satu untuk setiap ukuran kunci yang digunakan) dan harus berisi perdana dan Generator (biasanya 2 atau 5) sebagai hex.

Jika Anda openssl dhparam -out dhparam2048.pem 2048menghasilkan pasangan baru, Anda dapat menggunakan openssl dhparam -noout -text -check -in dhparam2048.pemuntuk membaca dan mencetak file itu dalam mode teks. Anda harus menyalin dan menempelkan teks ke properti keamanan Java (gunakan tr -d ':'untuk menghapus :antara representasi hex openssl)

Berikut adalah contoh (1024 bis saja):

>openssl dhparam -in p -check -text -noout | tr -d ':'
PKCS#3 DH Parameters: (1024 bit)
    prime:
       00f7a63b59edcc43a43df12077f0e9
        14129c20a73cef95f919896e608ebc
        8722776c948765bbbf61542e118329
        6c6ea74ecbded3a93aff77a062aba4
        fcf04fc01030e65077f5a802605058
        65b836368dd5ea389d77691fac0f2c
        f7a161c51c8e97ddecb3cf7f872b0c
        cfaf54373d5203edcabc575e871bb1
        107ec2f30c78ebf403
    generator: 2 (0x2)
DH parameters appear to be ok.

Dan ini menghasilkan

jdk.tls.server.defaultDHEParameters= \
    { \
        00f7a63b59edcc43a43df12077f0e9 \
        14129c20a73cef95f919896e608ebc \
        8722776c948765bbbf61542e118329 \
        6c6ea74ecbded3a93aff77a062aba4 \
        fcf04fc01030e65077f5a802605058 \
        65b836368dd5ea389d77691fac0f2c \
        f7a161c51c8e97ddecb3cf7f872b0c \
        cfaf54373d5203edcabc575e871bb1 \
        107ec2f30c78ebf403, 2 }

Anda harus me-restart Server dan memverifikasi bahwa itu benar-benar menggunakan prime ini (dan bukan yang default) karena prosesnya tidak lurus ke depan, sehingga banyak yang bisa salah. Default didefinisikan dalam sumber , untuk 2048 bit yang utama adalah dari TLS FFDHE draft.

Sebagai contoh ketika menjalankan openssl s_client, saya dapat melihat 1024bit prime ( ffffff ffffffffffc90f ... 5381ffffffffffffffffff ) saat menghubungkan ke Java 8 JSSE Server:

>openssl s_client -msg -cipher DHE-RSA-AES128-SHA256 -connect localhost:1234
...
<<< TLS 1.2 Handshake [length 018f], ServerKeyExchange
0c 00 01 8b 00 80 ff ff ff ff ff ff ff ff c9 0f
da a2 21 68 c2 34 c4 c6 62 8b 80 dc 1c d1 29 02
4e 08 8a 67 cc 74 02 0b be a6 3b 13 9b 22 51 4a
08 79 8e 34 04 dd ef 95 19 b3 cd 3a 43 1b 30 2b
0a 6d f2 5f 14 37 4f e1 35 6d 6d 51 c2 45 e4 85
b5 76 62 5e 7e c6 f4 4c 42 e9 a6 37 ed 6b 0b ff
5c b6 f4 06 b7 ed ee 38 6b fb 5a 89 9f a5 ae 9f
24 11 7c 4b 1f e6 49 28 66 51 ec e6 53 81 ff ff
ff ff ff ff ff ff 00 01 02 ...

Alih-alih ini, Anda harus melihat Parameter khusus Anda saat diinstal.

Parameter Default untuk Java 7 (768bit) adalah "e9e642 ... 7a3daf" dengan generator panjang "30470ad..529252" sebagaimana didefinisikan dalam ParameterCache .

eek
sumber
3

Saya sudah mengalami masalah yang sama, tetapi dari Glassfish.

Pertama, saya akan merekomendasikan (jika Anda bisa) untuk meletakkan semacam proxy terbalik di depan server JBoss Anda karena akan menghapus tautan antara keamanan sandi / sertifikat dan versi Java yang Anda jalankan.

Untuk mendapatkan panjang kunci Ephemeral DH yang lebih besar dari 768 bit, Anda harus menjalankannya di Java 8. 1024 adalah default baru, dan Anda bisa mencapai 2048 menggunakan jdk.tls.ephemeralDHKeySize(detail: mengkustomisasi kunci DH ). Dari apa yang saya dapat temukan, tidak ada konsep regenerasi parameter kunci secara terpisah di Jawa.

David Hutchison
sumber
Terima kasih atas saran alternatif ini. Kami mungkin melihat ini di masa depan.
user2072931
Sekarang ada, lihat serverfault.com/a/798036/4591
eckes
untuk GlassFish / payara / payara-mikro untuk menonaktifkan DHE cipher menambahkan <ssl tls-enabled="false" classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" tls11-enabled="false" cert-nickname="s1as" ssl3-tls-ciphers="+TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA256,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA256,+TLS_ECDH_RSA_WITH_AES_256_GCM_SHA256"></ssl>ke <protocol name="http-listener-2" security-enabled="true">konektor SSL
Markus