Pertanyaan Bagaimana mengatasi kesalahan javax.net.ssl.SSLHandshakeException?


Saya terhubung dengan VPN untuk menyiapkan API inventaris untuk mendapatkan daftar produk dan berfungsi dengan baik. Setelah saya mendapatkan hasil dari layanan web dan saya mengikat ke UI. Dan juga saya mengintegrasikan PayPal dengan aplikasi saya untuk melakukan checkout Express ketika saya melakukan panggilan untuk pembayaran Saya menghadapi kesalahan ini. Saya menggunakan servlet untuk proses back-end. Bisakah ada yang mengatakan cara memperbaiki masalah ini?

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

75
2017-07-12 04:03


asal


Jawaban:


Pertama Anda perlu mendapatkan sertifikat publik dari server yang Anda coba sambungkan. Itu bisa dilakukan dengan berbagai cara, seperti menghubungi admin server dan memintanya, menggunakan openssl untuk mengunduhnya, atau, karena ini tampaknya adalah server HTTP, menyambungkannya dengan browser apa pun, melihat info keamanan halaman, dan menyimpan salinan sertifikat. (Google harus dapat memberi tahu Anda apa yang harus dilakukan untuk peramban khusus Anda.)

Sekarang Anda memiliki sertifikat yang disimpan dalam file, Anda perlu menambahkannya ke toko kepercayaan JVM Anda. Di $JAVA_HOME/jre/lib/security/ untuk JRE atau $JAVA_HOME/lib/security untuk JDK, ada file bernama cacerts, yang datang dengan Java dan berisi sertifikat publik dari Otoritas Sertifikasi yang terkenal. Untuk mengimpor sertifikat baru, jalankan keytool sebagai pengguna yang memiliki izin untuk menulis ke cacerts:

keytool -import -file <the cert file> -alias <some meaningful name> -keystore <path to cacerts file>

Kemungkinan besar Anda akan meminta kata sandi. Kata sandi standar seperti yang dikirimkan dengan java changeit. Hampir tidak ada yang mengubahnya. Setelah Anda menyelesaikan langkah-langkah yang relatif sederhana ini, Anda akan berkomunikasi dengan aman dan dengan jaminan bahwa Anda berbicara dengan server yang tepat dan hanya server yang tepat (selama mereka tidak kehilangan kunci pribadi mereka).


114
2017-07-19 04:08



Sekarang saya memecahkan masalah ini dengan cara ini,

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.OutputStream; 

// Create a trust manager that does not validate certificate chains like the default 

TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {

            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
            {
                //No need to implement.
            }
        }
};

// Install the all-trusting trust manager
try 
{
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} 
catch (Exception e) 
{
    System.out.println(e);
}

Tentu saja solusi ini hanya boleh digunakan dalam skenario, di mana tidak mungkin menginstal sertifikat yang diperlukan keytool misalnya pengujian lokal dengan sertifikat temporer.


14
2017-07-19 03:52



Setiap kali kami mencoba menyambung ke URL,

jika server di situs lain berjalan pada protokol https dan mewajibkan bahwa kita harus berkomunikasi melalui informasi yang diberikan dalam sertifikat itu       kami memiliki opsi berikut:

1) minta sertifikat (unduh sertifikat), impor sertifikat ini di trustore. Penggunaan java trustore default dapat ditemukan di \ Java \ jdk1.6.0_29 \ jre \ lib \ security \ cacerts, kemudian jika kita mencoba untuk terhubung ke koneksi URL akan diterima.

2) Dalam kasus bisnis normal, kami mungkin terhubung ke URL internal dalam organisasi dan kami tahu bahwa mereka benar.          Dalam kasus seperti itu, Anda percaya bahwa itu adalah URL yang benar, Dalam kasus seperti di atas, kode dapat digunakan yang tidak akan mandat untuk menyimpan sertifikat untuk terhubung ke URL tertentu.

untuk poin no 2 kita harus mengikuti langkah-langkah di bawah ini:

1) tulis metode di bawah ini yang menetapkan HostnameVerifier untuk HttpsURLConnection yang mengembalikan true untuk semua kasus yang berarti kita mempercayai trustStore.

  // trusting all certificate 
 public void doTrustToCertificates() throws Exception {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                        return;
                    }
                }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

2) tulis metode di bawah ini, yang memanggil doTrustToCertificates sebelum mencoba menyambung ke URL

    // connecting to URL
    public void connectToUrl(){
     doTrustToCertificates();//  
     URL url = new URL("https://www.example.com");
     HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
     System.out.println("ResponseCode ="+conn.getResponseCode());
   }

Panggilan ini akan mengembalikan kode respons = 200 berarti koneksi berhasil.

Untuk lebih detail dan contoh contoh Anda bisa merujuk URL.


10
2018-03-20 05:54



Saya yakin Anda mencoba menyambung ke sesuatu menggunakan SSL, tetapi ada sesuatu yang memberikan sertifikat yang tidak diverifikasi oleh otoritas sertifikasi akar seperti verisign. Pada dasarnya, koneksi aman default hanya dapat dibuat jika orang yang mencoba terhubung tahu kunci rekanan atau verndor lain seperti verisign dapat masuk dan mengatakan bahwa kunci publik yang disediakan memang benar ..

SEMUA kepercayaan OS segelintir otoritas sertifikasi dan penerbit sertifikat yang lebih kecil harus disertifikasi oleh salah satu pemberi sertifikat besar yang membuat rantai pengesah jika Anda mengerti maksud saya ...

Ngomong-ngomong kembali ke pokoknya .. Saya memiliki masalah yang sama ketika memrogram java applet dan server java (Semoga suatu hari nanti saya akan menulis blog lengkap tentang bagaimana saya mendapatkan semua keamanan untuk bekerja :))

Intinya apa yang harus saya lakukan adalah mengekstrak kunci publik dari server dan menyimpannya dalam keystore di dalam applet saya dan ketika saya terhubung ke server saya menggunakan toko kunci ini untuk membuat pabrik kepercayaan dan pabrik kepercayaan untuk membuat ssl koneksi. Ada juga prosedur alterante seperti menambahkan kunci ke host tepercaya JVM dan memodifikasi trust store default saat start up ..

Saya melakukan ini sekitar dua bulan yang lalu dan tidak memiliki kode sumber pada saya sekarang .. gunakan google dan Anda harus dapat memecahkan masalah ini. Jika Anda tidak dapat mengirim pesan saya kembali dan saya dapat memberikan Anda kode sumber yang relevan untuk proyek tersebut. Tidak tahu jika ini memecahkan masalah Anda karena Anda belum menyediakan kode yang menyebabkan pengecualian ini. Selanjutnya saya bekerja dengan applet pikir saya tidak bisa melihat mengapa tidak akan bekerja pada Serverlets ...

P.S Saya tidak dapat memperoleh kode sumber sebelum akhir pekan karena SSH eksternal dinonaktifkan di kantor saya :(


0
2017-07-14 17:53



SSLHandshakeException dapat diatasi dengan 2 cara.

  1. Menggabungkan SSL

    • Dapatkan SSL (dengan menanyakan administrator sistem sumber, bisa juga diunduh oleh perintah openssl, atau unduhan browser apa pun sertifikat)

    • Tambahkan sertifikat ke truststore (cacerts) yang terletak di JRE / lib / keamanan

    • memberikan lokasi truststore dalam argumen vm sebagai "-Djavax.net.ssl.trustStore ="

  2. Mengabaikan SSL

    Untuk # 2 ini, silakan kunjungi jawaban saya yang lain di situs web stackoverflow lain: Bagaimana cara melakukan verifikasi SSL Abaikan Kesalahan Sertifikat SSL dengan Java


0
2018-03-16 02:04



Sekarang saya memecahkan masalah ini dengan cara ini,

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.OutputStream;
// Create a trust manager that does not validate certificate chains like the 
default TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //No need to implement. 
        }
        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            //No need to implement. 
        }
    }
};
// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
    System.out.println(e);
}

-3
2017-11-30 01:26