Saya menggunakan Java 6 dan mencoba membuat HttpsURLConnection
server jauh melawan, menggunakan sertifikat klien.
Server menggunakan sertifikat akar yang ditandatangani sendiri, dan mengharuskan sertifikat klien yang dilindungi sandi disajikan. Saya telah menambahkan sertifikat root server dan sertifikat klien ke keystore java default yang saya temukan di /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts
(OSX 10.5). Nama file keystore sepertinya menyarankan bahwa sertifikat klien tidak seharusnya masuk ke sana?
Bagaimanapun, menambahkan sertifikat root ke toko ini menyelesaikan masalah yang terkenal itu javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.
Namun, saya sekarang terjebak pada cara menggunakan sertifikat klien. Saya sudah mencoba dua pendekatan dan tidak membawa saya kemana-mana.
Pertama, dan lebih disukai, coba:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Saya telah mencoba melewatkan kelas HttpsURLConnection (tidak ideal karena saya ingin berbicara tentang HTTP dengan server), dan melakukan ini sebagai gantinya:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out
Saya bahkan tidak yakin bahwa sertifikat klien adalah masalahnya di sini.
Jawaban:
Akhirnya dipecahkan;). Punya petunjuk kuat di sini (jawaban Gandalf sedikit menyinggung soal itu juga). Tautan yang hilang (kebanyakan) adalah yang pertama dari parameter di bawah ini, dan sampai batas tertentu saya mengabaikan perbedaan antara keystore dan truststore.
Sertifikat server yang ditandatangani sendiri harus diimpor ke truststore:
Properti ini perlu disetel (baik di baris perintah, atau dalam kode):
Kode contoh kerja:
sumber
Meskipun tidak disarankan, Anda juga dapat menonaktifkan validasi sertifikat SSL sekaligus:
sumber
Sudahkah Anda menyetel properti KeyStore dan / atau TrustStore System?
atau dari dengan kode
Sama dengan javax.net.ssl.trustStore
sumber
Jika Anda berurusan dengan panggilan layanan web menggunakan kerangka kerja Axis, ada jawaban yang jauh lebih sederhana. Jika semua yang diinginkan adalah klien Anda dapat memanggil layanan web SSL dan mengabaikan kesalahan sertifikat SSL, cukup letakkan pernyataan ini sebelum Anda menjalankan layanan web apa pun:
System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");
Penafian biasa tentang hal ini sebagai Hal yang Sangat Buruk yang harus dilakukan di lingkungan produksi berlaku.
Saya menemukan ini di wiki Axis .
sumber
Bagi saya, inilah yang berhasil menggunakan Apache HttpComponents ~ HttpClient 4.x:
File P12 berisi sertifikat klien dan kunci pribadi klien, yang dibuat dengan BouncyCastle:
sumber
keyStore
yang berisi kunci pribadi dan sertifikat.Saya menggunakan paket Klien HTTP Apache commons untuk melakukan ini dalam proyek saya saat ini dan berfungsi dengan baik dengan SSL dan sertifikat yang ditandatangani sendiri (setelah menginstalnya ke cacert seperti yang Anda sebutkan). Silakan lihat di sini:
http://hc.apache.org/httpclient-3.x/tutorial.html
http://hc.apache.org/httpclient-3.x/sslguide.html
sumber
SSLContext
langsung, sehingga Anda dapat mengkonfigurasi semua ini dengan cara ini, daripada menggunakanAuthSSLProtocolSocketFactory
.Saya rasa Anda memiliki masalah dengan sertifikat server Anda, bukan sertifikat yang valid (menurut saya inilah yang dimaksud dengan "handshake_failure" dalam kasus ini):
Impor sertifikat server Anda ke keystore trustcacerts Anda pada JRE klien. Ini mudah dilakukan dengan keytool :
sumber
Menggunakan kode di bawah ini
atau
sama sekali tidak diperlukan. Juga tidak perlu membuat pabrik SSL kustom Anda sendiri.
Saya juga mengalami masalah yang sama, dalam kasus saya ada masalah bahwa rantai sertifikat lengkap tidak diimpor ke truststore. Impor sertifikat menggunakan utilitas keytool tepat dari sertifikat root, Anda juga dapat membuka file cacerts di notepad dan melihat apakah rantai sertifikat lengkap diimpor atau tidak. Periksa dengan nama alias yang Anda berikan saat mengimpor sertifikat, buka sertifikat dan lihat berapa isinya, jumlah sertifikat yang sama harus ada di file cacerts.
File cacerts juga harus dikonfigurasi di server tempat Anda menjalankan aplikasi, kedua server akan mengautentikasi satu sama lain dengan kunci publik / pribadi.
sumber