Saya sedang mengembangkan aplikasi Java yang meminta REST API di server jarak jauh melalui HTTP. Untuk alasan keamanan, komunikasi ini harus dialihkan ke HTTPS.
Sekarang Let's Encrypt memulai beta publik mereka, saya ingin tahu apakah Java saat ini berfungsi (atau dipastikan akan berfungsi di masa depan) dengan sertifikat mereka secara default.
Let's Encrypt mendapat tanda tangan silang perantara mereka oleh IdenTrust , yang seharusnya menjadi kabar baik. Namun, saya tidak dapat menemukan salah satu dari keduanya di output dari perintah ini:
keytool -keystore "..\lib\security\cacerts" -storepass changeit -list
Saya tahu bahwa CA tepercaya dapat ditambahkan secara manual di setiap mesin, tetapi karena aplikasi saya seharusnya dapat diunduh dan dijalankan secara gratis tanpa konfigurasi lebih lanjut, saya mencari solusi yang berfungsi "di luar kotak". Apakah Anda punya kabar baik untuk saya?
Jawaban:
[ Pembaruan 2016-06-08 : Menurut https://bugs.openjdk.java.net/browse/JDK-8154757 , IdenTrust CA akan disertakan dalam Oracle Java 8u101.]
[ Pembaruan 2016-08-05 : Java 8u101 telah dirilis dan memang menyertakan IdenTrust CA: catatan rilis ]
Iya. Sertifikat Let's Encrypt hanyalah sertifikat kunci publik biasa. Java mendukungnya (menurut Let's Encrypt Certificate Compatibility , untuk Java 7> = 7u111 dan Java 8> = 8u101).
Tidak / itu tergantung pada JVM. Truststore Oracle JDK / JRE hingga 8u66 tidak berisi Let's Encrypt CA secara khusus maupun IdenTrust CA yang menandatanganinya.
new URL("https://letsencrypt.org/").openConnection().connect();
misalnya menghasilkanjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException
.Namun Anda dapat memberikan validator Anda sendiri / menentukan keystore khusus yang berisi CA root yang diperlukan atau mengimpor sertifikat ke truststore JVM.
https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/10 juga membahas topik tersebut.
Berikut beberapa contoh kode yang menunjukkan cara menambahkan sertifikat ke truststore default pada waktu proses. Anda hanya perlu menambahkan sertifikat (diekspor dari firefox sebagai .der dan dimasukkan ke classpath)
Berdasarkan Bagaimana cara mendapatkan daftar sertifikat dasar tepercaya di Java? dan http://developer.android.com/training/articles/security-ssl.html#UnknownCa
sumber
isrgrootx1.der
danlets-encrypt-x1-cross-signed.der
, tetapi tidak satu pun dari mereka tampaknya yang benar.https://helloworld.letsencrypt.org
misalnya dan periksa rantai sertifikat di browser (mengklik ikon hijau). Untuk yang satu ini, Anda memerlukan sertifikat khusus situs, sertifikat perantara X1 (ditandatangani silang oleh IdenTrust) atau yang DSTRootCAX3. TidakISRG Root X1
berfungsi untuk situs helloworld karena tidak ada dalam rantai, itu adalah rantai alternatif. Saya akan menggunakan DSTRoot, cukup diekspor melalui browser karena saya belum melihatnya untuk diunduh di mana pun.javax.net.ssl.trustStore
properti sistem, tetapi -1 untuk kemudian mengatur default JVMSSLContext
. Akan lebih baik untuk membuat yang baruSSLSocketFactory
dan kemudian menggunakannya untuk berbagai koneksi (misalnyaHttpUrlConnection
) daripada mengganti konfigurasi SSL di seluruh VM. (Saya menyadari perubahan ini hanya efektif untuk menjalankan JVM dan tidak bertahan atau mempengaruhi program lain. Saya hanya berpikir itu adalah praktik pemrograman yang lebih baik untuk secara eksplisit tentang di mana konfigurasi Anda berlaku.)Saya tahu OP meminta solusi tanpa perubahan konfigurasi lokal, tetapi jika Anda ingin menambahkan rantai kepercayaan ke keystore secara permanen:
sumber: https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/13
sumber
Jawaban mendetail bagi kami yang ingin membuat perubahan konfigurasi lokal yang mencakup mencadangkan file konfigurasi:
1. Uji apakah itu berfungsi sebelum perubahan
Jika Anda belum memiliki program pengujian, Anda dapat menggunakan program ping SSLPing java saya yang menguji handshake TLS (akan bekerja dengan port SSL / TLS apa pun, bukan hanya HTTPS). Saya akan menggunakan SSLPing.jar prebuilt, tetapi membaca kode dan membuatnya sendiri adalah tugas yang cepat dan mudah:
Karena versi Java saya lebih awal dari 1.8.0_101 (tidak dirilis pada saat penulisan ini), sertifikat Let's Encrypt tidak akan diverifikasi secara default. Mari kita lihat seperti apa kegagalan sebelum menerapkan perbaikan:
2. Impor sertifikat
Saya menggunakan Mac OS X dengan kumpulan variabel lingkungan JAVA_HOME. Perintah selanjutnya akan menganggap variabel ini disetel untuk instalasi java yang Anda ubah:
Buat cadangan file cacerts yang akan kami modifikasi sehingga Anda dapat mencadangkan perubahan apa pun tanpa menginstal ulang JDK:
Unduh sertifikat penandatanganan yang perlu kami impor:
Lakukan impor:
3. Verifikasi bahwa ini berfungsi setelah perubahan
Pastikan Java sekarang dengan senang hati terhubung ke port SSL:
sumber
Untuk JDK yang belum mendukung sertifikat Let's Encrypt, Anda dapat menambahkannya ke JDK
cacerts
setelah proses ini (terima kasih untuk ini ).Unduh semua sertifikat di https://letsencrypt.org/certificates/ (pilih format der ) dan tambahkan satu per satu dengan perintah seperti ini (contoh untuk
letsencryptauthorityx1.der
):sumber