Sepertinya pertanyaan standar, tapi saya tidak bisa menemukan arah yang jelas di mana pun.
Saya memiliki kode java yang mencoba terhubung ke server dengan sertifikat yang ditandatangani sendiri (atau kedaluwarsa). Kode melaporkan kesalahan berikut:
[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught
when processing request: sun.security.validator.ValidatorException: PKIX path
building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Seperti yang saya pahami, saya harus menggunakan keytool dan memberi tahu java bahwa boleh saja mengizinkan koneksi ini.
Semua instruksi untuk memperbaiki masalah ini menganggap saya sepenuhnya mahir dengan keytool, seperti
buat kunci pribadi untuk server dan impor ke keystore
Adakah orang yang dapat memposting instruksi terperinci?
Saya menjalankan unix, jadi skrip bash akan menjadi yang terbaik.
Tidak yakin apakah ini penting, tetapi kode dieksekusi di jboss.
Jawaban:
Pada dasarnya Anda memiliki dua opsi di sini: tambahkan sertifikat yang ditandatangani sendiri ke toko kepercayaan JVM Anda atau konfigurasikan klien Anda
Pilihan 1
Ekspor sertifikat dari browser Anda dan impor di truststore JVM Anda (untuk membangun rantai kepercayaan):
pilihan 2
Nonaktifkan Validasi Sertifikat:
Perhatikan bahwa saya tidak merekomendasikan Opsi # 2 sama sekali . Menonaktifkan manajer kepercayaan mengalahkan beberapa bagian SSL dan membuat Anda rentan terhadap serangan tengah. Lebih suka Opsi # 1 atau, bahkan lebih baik, memiliki server menggunakan sertifikat "nyata" yang ditandatangani oleh CA terkenal.
sumber
Saya mengejar masalah ini ke penyedia sertifikat yang bukan bagian dari host tepercaya JVM default
JDK 8u74
. Penyedia adalah www.identrust.com , tetapi itu bukan domain yang saya coba sambungkan. Domain itu telah mendapatkan sertifikat dari penyedia ini. Lihat Akankah cross root percaya dengan daftar default di JDK / JRE? - Baca beberapa entri. Juga lihat Browser dan sistem operasi mana yang mendukung Let's Encrypt .Jadi, untuk menghubungkan ke domain saya tertarik, yang memiliki sertifikat yang dikeluarkan dari
identrust.com
saya lakukan langkah-langkah berikut. Pada dasarnya, saya harus mendapatkan identrust.com (DST Root CA X3
sertifikat ) agar dipercaya oleh JVM. Saya dapat melakukannya dengan menggunakan Apache HttpComponents 4.5 seperti:1: Dapatkan sertifikat dari indettrust di Petunjuk Unduhan Rantai Sertifikat . Klik tautan DST Root CA X3 .
2: Simpan string ke file bernama "DST Root CA X3.pem". Pastikan untuk menambahkan baris "----- BEGIN CERTIFICATE -----" dan "----- END CERTIFICATE -----" dalam file di awal dan akhir.
3: Buat file java keystore, cacerts.jks dengan perintah berikut:
4: Salin keystore cacerts.jks yang dihasilkan ke direktori sumber daya aplikasi java / (maven) Anda.
5: Gunakan kode berikut untuk memuat file ini dan lampirkan ke Apache 4.5 HttpClient. Ini akan menyelesaikan masalah untuk semua domain yang memiliki sertifikat yang dikeluarkan dari
indetrust.com
util oracle menyertakan sertifikat ke dalam keystore default JRE.Ketika proyek dibangun maka cacerts.jks akan disalin ke classpath dan diambil dari sana. Saya tidak, pada saat ini, menguji terhadap situs ssl lain, tetapi jika kode di atas "rantai" dalam sertifikat ini maka mereka akan bekerja juga, tapi sekali lagi, saya tidak tahu.
Referensi: Konteks SSL khusus dan Bagaimana cara saya menerima sertifikat yang ditandatangani sendiri dengan Java HttpsURLConnection?
sumber
Apache HttpClient 4.5 mendukung penerimaan sertifikat yang ditandatangani sendiri:
Ini membangun pabrik soket SSL yang akan menggunakan
TrustSelfSignedStrategy
, mendaftar dengan manajer koneksi kustom kemudian melakukan GET HTTP menggunakan manajer koneksi itu.Saya setuju dengan mereka yang menyapa "jangan lakukan ini dalam produksi", namun ada kasus penggunaan untuk menerima sertifikat yang ditandatangani sendiri di luar produksi; kami menggunakannya dalam pengujian integrasi otomatis, sehingga kami menggunakan SSL (seperti dalam produksi) bahkan ketika tidak berjalan pada perangkat keras produksi.
sumber
Daripada mengatur pabrik soket default (yang IMO adalah hal yang buruk) - dia hanya akan mempengaruhi koneksi saat ini daripada setiap koneksi SSL yang Anda coba buka:
sumber
checkServerTrusted
tidak menerapkan logika yang diperlukan untuk benar-benar mempercayai sertifikat dan memastikan sertifikat yang tidak dipercaya ditolak. Ini mungkin membuat pembacaan yang baik: Kode paling berbahaya di dunia: memvalidasi sertifikat SSL dalam perangkat lunak non-browser .getAcceptedIssuers()
metode tidak sesuai dengan specifcation, dan ini 'solusi' tetap radikal tidak aman.Ada alternatif yang lebih baik untuk mempercayai semua sertifikat: Buat sertifikat
TrustStore
yang secara khusus mempercayai sertifikat yang diberikan dan gunakan ini untuk membuatSSLContext
dari mana untuk mendapatkanSSLSocketFactory
set ke padaHttpsURLConnection
. Berikut kode lengkapnya:Anda juga dapat memuat
KeyStore
langsung dari file atau mengambil Sertifikat X.509 dari sumber tepercaya.Perhatikan bahwa dengan kode ini, sertifikat di
cacerts
tidak akan digunakan. Khusus iniHttpsURLConnection
hanya akan mempercayai sertifikat khusus ini.sumber
Percayai semua sertifikat SSL: - Anda dapat mengabaikan SSL jika Anda ingin menguji pada server pengujian. Tetapi jangan gunakan kode ini untuk produksi.
}
Silakan panggil fungsi ini di fungsi onCreate () di Activity atau di Kelas Aplikasi Anda.
Ini dapat digunakan untuk Volley di Android.
sumber
Jawaban yang diterima baik-baik saja, tetapi saya ingin menambahkan sesuatu ke ini karena saya menggunakan IntelliJ di Mac dan tidak bisa membuatnya bekerja menggunakan
JAVA_HOME
variabel path.Ternyata Java Home berbeda ketika menjalankan aplikasi dari IntelliJ.
Untuk mencari tahu persis di mana letaknya, Anda bisa melakukan apa saja
System.getProperty("java.home")
di mana sertifikat tepercaya dibaca.sumber
Jika 'mereka' menggunakan sertifikat yang ditandatangani sendiri, tergantung pada mereka untuk mengambil langkah-langkah yang diperlukan agar server mereka dapat digunakan. Khususnya itu berarti memberikan sertifikat kepada Anda secara offline dengan cara yang dapat dipercaya. Jadi suruh mereka melakukan itu. Anda kemudian mengimpornya ke truststore Anda menggunakan keytool seperti yang dijelaskan dalam Panduan Referensi JSSE. Jangan pernah berpikir tentang TrustManager yang tidak aman yang diposting di sini.
EDIT Untuk kepentingan tujuh belas (!) Downvoters, dan banyak komentator di bawah ini, yang jelas belum benar-benar membaca apa yang saya tulis di sini, ini bukan jeremiad terhadap sertifikat yang ditandatangani sendiri. Tidak ada yang salah dengan sertifikat yang ditandatangani sendiri ketika diterapkan dengan benar. Tetapi, cara yang benar untuk mengimplementasikannya adalah memiliki sertifikat yang dikirimkan secara aman melalui proses offline, daripada melalui saluran yang tidak diautentikasi yang akan mereka gunakan untuk mengotentikasi. Tentunya ini jelas? Jelas sekali bagi setiap organisasi yang sadar akan keamanan yang pernah saya bekerja, dari bank dengan ribuan cabang hingga perusahaan saya sendiri. 'Solusi' basis kode sisi klien untuk mempercayai semuasertifikat, termasuk sertifikat yang ditandatangani sendiri yang ditandatangani oleh siapa saja, atau badan arbiter yang mengatur dirinya sendiri sebagai CA, ipso factotidak aman Itu hanya bermain di keamanan. Tidak ada gunanya. Anda memiliki percakapan pribadi, tamperproof, proof-proof, proof-injection dengan ... seseorang. Siapa saja. Seorang pria di tengah. Peniru. Siapa saja. Anda juga bisa menggunakan plaintext.
sumber
Ini bukan solusi untuk masalah lengkap tetapi oracle memiliki dokumentasi terperinci yang baik tentang cara menggunakan keytool ini. Ini menjelaskan caranya
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178
sumber
Alih-alih menggunakan keytool seperti yang disarankan oleh komentar teratas, di RHEL Anda dapat menggunakan pembaruan-ca-trust mulai dalam versi yang lebih baru dari RHEL 6. Anda harus memiliki sertifikat dalam format pem. Kemudian
Edit /etc/pki/ca-trust/source/cert.p11-kit dan ubah "kategori sertifikat: entri-lain" menjadi "kategori sertifikat: otoritas". (Atau gunakan sed untuk melakukan ini dalam skrip.) Lalu lakukan
Beberapa peringatan:
update-ca-trust enable
. Ini akan menggantikan / etc / pki / java / cacerts dengan tautan simbolik yang menunjuk ke / etc / pki / ca-trust / extracted / java / cacerts. (Jadi, Anda mungkin ingin mencadangkan yang pertama.)sumber
Saya memiliki masalah ketika saya mengirimkan URL ke perpustakaan yang memanggil
url.openConnection();
saya mengadaptasi jawaban jon-daniel,Menggunakan kelas ini dimungkinkan untuk membuat URL baru dengan:
Ini memiliki keuntungan bahwa itu dilokalkan dan tidak menggantikan default
URL.openConnection
.sumber