Saya memiliki masalah dengan koneksi SSL resmi. Saya telah membuat Tindakan Struts yang menghubungkan ke server eksternal dengan sertifikat SSL Resmi Klien. Dalam Tindakan saya, saya mencoba mengirim beberapa data ke server bank tetapi tidak berhasil, karena saya memiliki kesalahan dari server sebagai berikut:
error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Metode saya dari kelas Tindakan saya yang mengirim data ke server
//Getting external IP from host
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
String IPStr = inIP.readLine(); //IP as a String
Merchant merchant;
System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);
try {
merchant = new Merchant(context.getRealPath("/") + "merchant.properties");
} catch (ConfigurationException e) {
Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
System.err.println("error: " + e.getMessage());
return ERROR;
}
String result = merchant.sendTransData(amount, currency, IPStr, description);
System.out.println("result: " + result);
return SUCCESS;
File properti pedagang saya:
bank.server.url=https://-servernameandport-/
https.cipher=-cipher-
keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0
encoding.source=UTF-8
encoding.native=UTF-8
Untuk pertama kalinya saya pikir ini adalah masalah sertifikat, saya mengonversinya dari .pfx ke .jks, tetapi saya memiliki kesalahan yang sama, tanpa perubahan.
Jawaban:
Kegagalan jabat tangan bisa terjadi karena berbagai alasan:
Karena, kegagalan mendasar tidak dapat ditunjukkan, lebih baik untuk mengaktifkan
-Djavax.net.debug=all
flag untuk mengaktifkan debugging koneksi SSL yang dibuat. Dengan debug diaktifkan, Anda dapat menentukan aktivitas apa yang gagal dalam jabat tangan.Memperbarui
Berdasarkan perincian yang sekarang tersedia, tampaknya masalahnya disebabkan oleh jalur perwalian sertifikat yang tidak lengkap antara sertifikat yang dikeluarkan ke server, dan root CA. Dalam kebanyakan kasus, ini karena sertifikat CA root tidak ada di toko kepercayaan, yang mengarah ke situasi di mana jalur kepercayaan sertifikat tidak ada; sertifikat pada dasarnya tidak dipercaya oleh klien. Browser dapat memberikan peringatan sehingga pengguna dapat mengabaikan ini, tetapi hal yang sama tidak berlaku untuk klien SSL (seperti kelas HttpsURLConnection , atau perpustakaan Klien HTTP seperti Klien Apache HttpComponents ).
Sebagian besar kelas / pustaka klien ini akan bergantung pada toko kepercayaan yang digunakan oleh JVM untuk validasi sertifikat. Dalam kebanyakan kasus, ini akan menjadi
cacerts
file di direktori JRE_HOME / lib / security. Jika lokasi toko kepercayaan telah ditentukan menggunakan properti sistem JVMjavax.net.ssl.trustStore
, maka toko di jalur itu biasanya yang digunakan oleh perpustakaan klien. Jika Anda ragu, lihatMerchant
kelas Anda , dan cari tahu kelas / pustaka yang digunakannya untuk membuat koneksi.Menambahkan sertifikat server yang mengeluarkan CA ke toko kepercayaan ini harus menyelesaikan masalah. Anda dapat merujuk ke jawaban saya pada pertanyaan terkait tentang cara mendapatkan alat untuk tujuan ini, tetapi utilitas Java keytool cukup untuk tujuan ini.
Peringatan : Toko kepercayaan pada dasarnya adalah daftar semua CA yang Anda percayai. Jika Anda memasukkan sertifikat yang bukan milik CA yang tidak Anda percayai, maka koneksi SSL / TLS ke situs yang memiliki sertifikat yang dikeluarkan oleh entitas itu dapat didekripsi jika kunci privat tersedia.
Pembaruan # 2: Memahami output dari jejak JSSE
Keystore dan truststores yang digunakan oleh JVM biasanya terdaftar di awal, agak seperti yang berikut:
Jika truststore yang salah digunakan, maka Anda harus mengimpor kembali sertifikat server ke yang benar, atau mengkonfigurasi ulang server untuk menggunakan yang terdaftar (tidak disarankan jika Anda memiliki beberapa JVM, dan semuanya digunakan untuk berbagai kebutuhan).
Jika Anda ingin memverifikasi apakah daftar sertifikat kepercayaan berisi sertifikat yang diperlukan, maka ada bagian yang sama, yang dimulai dengan:
Anda harus mencari apakah CA server adalah subjek.
Proses jabat tangan akan memiliki beberapa entri yang menonjol (Anda harus tahu SSL untuk memahaminya secara detail, tetapi untuk tujuan debugging masalah saat ini, cukuplah untuk mengetahui bahwa handshake_failure biasanya dilaporkan di ServerHello.
1. ClientHello
Serangkaian entri akan dilaporkan ketika koneksi sedang diinisialisasi. Pesan pertama yang dikirim oleh klien dalam pengaturan koneksi SSL / TLS adalah pesan ClientHello, biasanya dilaporkan dalam log sebagai:
Perhatikan cipher suite yang digunakan. Ini mungkin harus setuju dengan entri dalam file merchant.properties Anda, untuk konvensi yang sama mungkin digunakan oleh perpustakaan bank. Jika konvensi yang digunakan berbeda, tidak ada alasan untuk khawatir, karena ServerHello akan menyatakan demikian, jika cipher suite tidak kompatibel.
2. ServerHello
Server merespons dengan ServerHello, yang akan menunjukkan apakah pengaturan koneksi dapat dilanjutkan. Entri dalam log biasanya dari jenis berikut:
Perhatikan paket sandi yang telah dipilihnya; suite terbaik ini tersedia untuk server dan klien. Biasanya suite sandi tidak ditentukan jika ada kesalahan. Sertifikat server (dan opsional seluruh rantai) dikirim oleh server, dan akan ditemukan dalam entri sebagai:
Jika verifikasi sertifikat berhasil, Anda akan menemukan entri yang mirip dengan:
Salah satu langkah di atas tidak akan berhasil, sehingga kegagalan handshake_f, untuk handshake biasanya selesai pada tahap ini (tidak benar-benar, tetapi tahap-tahap berikutnya dari handshake biasanya tidak menyebabkan kegagalan handshake). Anda harus mengetahui langkah mana yang gagal, dan memposting pesan yang sesuai sebagai pembaruan untuk pertanyaan (kecuali Anda sudah memahami pesannya, dan Anda tahu apa yang harus dilakukan untuk menyelesaikannya).
sumber
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
perintah untuk mencetak konten. Kemudian verifikasi apakah sertifikat dalam cacerts cocok dengan CA dari sertifikat bank.changeit
. Kecuali jika itu diubah.Menginstal Java Cryptography Extension (JCE) Kekuatan Tidak Terbatas ( untuk JDK7 | untuk JDK8 ) mungkin memperbaiki bug ini. Buka zip file dan ikuti readme untuk menginstalnya.
sumber
Kegagalan jabat tangan bisa menjadi implementasi protokol TLSv1 yang bermasalah.
Dalam kasus kami ini membantu dengan java 7:
JVM akan bernegosiasi dalam urutan ini. Server dengan pembaruan terbaru akan melakukan 1.2, yang kereta akan turun ke v1 dan yang bekerja dengan v1 serupa di java 7.
sumber
Ini juga bisa terjadi ketika klien perlu menunjukkan sertifikat. Setelah server mencantumkan rantai sertifikat, hal berikut dapat terjadi:
3. Permintaan Sertifikat Server akan mengeluarkan permintaan sertifikat dari klien. Permintaan akan mencantumkan semua sertifikat yang diterima server.
4. Rantai Sertifikat Klien Ini adalah sertifikat yang dikirim klien ke server.
Jika tidak ada sertifikat di rantai dan server memerlukannya, Anda akan mendapatkan kesalahan jabat tangan di sini. Kemungkinan penyebabnya adalah jalur ke sertifikat Anda tidak ditemukan.
5. Verifikasi Sertifikat Klien meminta server untuk memverifikasi sertifikat
Langkah ini hanya akan terjadi jika Anda mengirim sertifikat.
6. Selesai Server akan merespons dengan respons verifikasi
sumber
Saya tidak berpikir ini menyelesaikan masalah kepada penanya pertama, tetapi bagi orang Google yang datang ke sini untuk mendapatkan jawaban:
Pada pembaruan 51, java 1.8 dilarang [1] RC4 cipher secara default, seperti yang bisa kita lihat di halaman Catatan Rilis:
Jika server Anda memiliki preferensi yang kuat untuk sandi ini (atau hanya gunakan sandi ini) ini dapat memicu
handshake_failure
pada java.Anda dapat menguji koneksi ke server yang mengaktifkan sandi RC4 (pertama, coba tanpa
enabled
argumen untuk melihat apakah pemicuhandshake_failure
, lalu aturenabled
:1 - https://www.java.com/en/download/faq/release_changes.xml
sumber
Saya memiliki kesalahan ini ketika saya mencoba menggunakan JDK 1.7. Ketika saya memutakhirkan JDK saya ke jdk1.8.0_66 semua mulai berfungsi dengan baik.
Jadi solusi paling sederhana untuk masalah ini adalah - tingkatkan JDK Anda dan itu bisa mulai berfungsi dengan baik.
sumber
Dalam kasus saya, cert diimpor, kesalahan tetap, diselesaikan dengan menambahkan
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
sebelum terhubungsumber
Dengan asumsi Anda menggunakan protokol SSL / TLS yang tepat, mengonfigurasi
keyStore
dantrustStore
, dan mengonfirmasi dengan benar bahwa tidak ada masalah dengan sertifikat itu sendiri, Anda mungkin perlu memperkuat algoritme keamanan Anda .Seperti disebutkan dalam jawaban Vineet , satu kemungkinan alasan Anda menerima kesalahan ini adalah karena suites cipher yang tidak kompatibel sedang digunakan. Dengan memperbarui guci
local_policy
danUS_export_policy
saya disecurity
folder JDK saya dengan yang disediakan di Java Cryptography Extension (JCE) , saya berhasil menyelesaikan jabat tangan.sumber
Saya menemui masalah yang sama hari ini dengan klien OkHttp untuk MENDAPATKAN url berbasis https. Itu disebabkan oleh versi protokol Https dan ketidaksesuaian metode Cipher antara sisi server dan sisi klien .
1) periksa situs web Anda https versi Protokol dan metode Cipher.openssl>s_client -connect your_website.com:443 -showcerts
Anda akan mendapatkan banyak info detail, info kunci terdaftar sebagai berikut:
2) konfigurasi klien http Anda, misalnya, dalam kasus klien OkHttp :Ini akan mendapatkan apa yang kita inginkan.
sumber
Saya menemukan server HTTPS yang gagal dengan cara ini jika proses klien Java saya dikonfigurasi dengan
Sambungan gagal dengan
handshake_failure
setelahServerHello
selesai tetapi sebelum aliran data dimulai.Tidak ada pesan kesalahan yang jelas yang mengidentifikasi masalah, kesalahannya hanya tampak
Saya mengisolasikan masalah dengan mencoba dengan dan tanpa opsi "
-Djsse.enableSNIExtension=false
"sumber
Milik saya adalah
TLS
kesalahan versi yang tidak kompatibel.Sebelumnya
TLSv1
saya mengubahnya,TLSV1.2
ini menyelesaikan masalah saya.sumber
Saya menggunakan klien http com.google.api. Ketika saya berkomunikasi dengan situs internal perusahaan, saya mendapatkan masalah ini ketika saya salah menggunakan https, bukan http.
sumber
Saya memiliki masalah serupa; meningkatkan ke Apache HTTPClient 4.5.3 memperbaikinya.
sumber
Ugg! Ini ternyata hanya menjadi masalah versi Java untuk saya. Saya mendapat kesalahan handshake menggunakan JRE 1.6 dan semuanya bekerja dengan baik menggunakan JRE 1.8.0_144.
sumber
Penafian: Saya tidak tahu apakah jawabannya akan bermanfaat bagi banyak orang, hanya berbagi karena mungkin.
Saya mendapatkan kesalahan ini saat menggunakan Parasoft SOATest untuk mengirim permintaan XML (SOAP).
Masalahnya adalah saya telah memilih alias yang salah dari dropdown setelah menambahkan sertifikat dan mengautentikasi itu.
sumber
Dalam kasus saya, situs web hanya dapat menggunakan TLSv1.2. dan saya menggunakan apache httpclient 4.5.6, saya menggunakan kode ini dan menginstal jce untuk menyelesaikan ini (JDK1.7):
jce
jdk7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
jdk 8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
kode:
sumber
Untuk memecahkan masalah dari perspektif pengembang (item 1) dan admin sistem (item 2 dan 3):
-Djavax.net.debug=ssl:handshake:verbose
.sudo apt install ssldump
atau kompilasi dari sumber dengan mengikuti tautan ini jika Anda mengamatiUnknown value
dalam sandi ketika Anda menjalankan langkah di bawah ini.sudo ssldump -k <your-private-key> -i <your-network-interface>
Contoh handshake log ssldump yang tidak berfungsi:
Contoh jabat tangan sukses dari ssldump log
Contoh log Java tidak berfungsi
sumber
Dalam kasus saya, saya punya satu masalah dengan versi 1.1. Saya mereproduksi masalah dengan mudah dengan ikal. Server tidak mendukung versi yang lebih rendah dari TLS1.2.
Masalah jabat tangan yang diterima ini:
Dengan versi 1.2 itu berfungsi dengan baik:
Server menjalankan Weblogic, dan menambahkan argumen ini di setEnvDomain.sh membuatnya bekerja dengan TLSv1.1:
sumber
Masalah ini terjadi karena versi java. Saya menggunakan 1.8.0.231 JDK dan mendapatkan kesalahan ini. Saya telah menurunkan versi java saya dari 1.8.0.231 ke 1.8.0.171, Sekarang Ini berfungsi dengan baik.
sumber