Chấp nhận chứng chỉ ssl tự ký của máy chủ trong máy khách Java


215

Nó trông giống như một câu hỏi tiêu chuẩn, nhưng tôi không thể tìm thấy hướng rõ ràng ở bất cứ đâu.

Tôi có mã java đang cố gắng kết nối với một máy chủ có chứng chỉ có thể tự ký (hoặc hết hạn). Mã báo cáo lỗi sau:

[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

Theo tôi hiểu, tôi phải sử dụng keytool và nói với java rằng không sao khi cho phép kết nối này.

Tất cả các hướng dẫn để khắc phục sự cố này giả sử tôi hoàn toàn thành thạo với keytool, chẳng hạn như

tạo khóa riêng cho máy chủ và nhập nó vào kho khóa

Có ai có thể gửi hướng dẫn chi tiết?

Tôi đang chạy unix, vì vậy bash script sẽ là tốt nhất.

Không chắc nó có quan trọng không, nhưng mã được thực thi trong jboss.


2
Xem Làm cách nào để tôi chấp nhận chứng chỉ tự ký với kết nối Java HttpsURLC? . Rõ ràng, sẽ tốt hơn nếu bạn có thể khiến trang web sử dụng chứng chỉ hợp lệ.
Matthew Flaschen

2
Cảm ơn liên kết, tôi đã không nhìn thấy nó trong khi tìm kiếm. Nhưng cả hai giải pháp đều có mã đặc biệt để gửi yêu cầu và tôi đang sử dụng mã hiện có (amazon ws client cho java). Về mặt tôn trọng, đó là trang web của họ tôi đang kết nối và tôi không thể khắc phục các sự cố chứng chỉ.
Nikita Rybak

2
@MatthewFlaschen - "Rõ ràng, sẽ tốt hơn nếu bạn có thể khiến trang web sử dụng chứng chỉ hợp lệ ..." - Chứng chỉ tự ký là chứng chỉ hợp lệ nếu khách hàng tin tưởng. Nhiều người cho rằng việc trao niềm tin cho cartel CA / Browser là một khiếm khuyết bảo mật.
ngày

3
Liên quan, xem Mã nguy hiểm nhất thế giới: xác nhận chứng chỉ SSL trong phần mềm không phải trình duyệt . (Liên kết được cung cấp vì bạn dường như nhận được những câu trả lời spam mà vô hiệu hóa xác nhận).
ngày

Câu trả lời:


306

Về cơ bản, bạn có hai tùy chọn: thêm chứng chỉ tự ký vào kho tin cậy JVM của bạn hoặc định cấu hình ứng dụng khách của bạn để

lựa chọn 1

Xuất chứng chỉ từ trình duyệt của bạn và nhập nó vào kho ủy thác JVM của bạn (để thiết lập chuỗi tin cậy):

<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit
-storepass changeit 

Lựa chọn 2

Vô hiệu hóa chứng chỉ:

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { 
    new X509TrustManager() {     
        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return new X509Certificate[0];
        } 
        public void checkClientTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
            } 
        public void checkServerTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
        }
    } 
}; 

// 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 (GeneralSecurityException e) {
} 
// Now you can access an https URL without having the certificate in the truststore
try { 
    URL url = new URL("https://hostname/index.html"); 
} catch (MalformedURLException e) {
} 

Lưu ý rằng tôi không đề xuất Tùy chọn # 2 nào cả . Vô hiệu hóa trình quản lý tin cậy đánh bại một số phần của SSL và khiến bạn dễ bị tổn thương bởi con người trong các cuộc tấn công ở giữa. Ưu tiên lựa chọn số 1 hoặc, thậm chí tốt hơn, để máy chủ sử dụng chứng chỉ "thực" được ký bởi một CA nổi tiếng.


7
Không chỉ là cuộc tấn công MIM. Nó khiến bạn dễ bị kết nối với trang web sai. Nó hoàn toàn không an toàn. Xem RFC 2246. Tôi phản đối việc đăng Trust Trustager này mọi lúc. Nó thậm chí không chính xác wrt đặc điểm kỹ thuật của riêng mình.
Hầu tước Lorne

10
@EJP Tôi thực sự không đề xuất tùy chọn thứ hai (Tôi đã cập nhật câu trả lời của mình để làm cho nó rõ ràng). Tuy nhiên, không đăng nó sẽ không giải quyết được bất cứ điều gì (đây là thông tin công khai) và IMHO không xứng đáng bị downvote.
Pascal Thivent

135
@EJP Đó là bằng cách dạy mọi người rằng bạn giáo dục họ, không phải bằng cách che giấu mọi thứ. Vì vậy, giữ mọi thứ bí mật hoặc tối nghĩa không phải là một giải pháp. Mã này là công khai, API Java là công khai, tốt hơn là nói về nó hơn là bỏ qua nó. Nhưng tôi có thể sống với bạn không đồng ý.
Pascal Thivent

10
Tùy chọn khác - tùy chọn bạn không đề cập - là sửa chứng chỉ của máy chủ bằng cách tự sửa hoặc bằng cách gọi cho những người hỗ trợ có liên quan. Chứng chỉ máy chủ duy nhất thực sự rất rẻ; làm phiền với những thứ tự ký là đồng xu ngu ngốc (nghĩa là, đối với những người không quen thuộc với thành ngữ tiếng Anh đó, một tập hợp ưu tiên hoàn toàn ngu ngốc có giá rất cao để tiết kiệm gần như không có gì).
Donal Fellows

2
@Rich, trễ 6 năm, nhưng bạn cũng có thể giữ chứng chỉ máy chủ trong firefox bằng cách nhấp vào biểu tượng khóa -> thêm thông tin -> Xem chứng chỉ -> tab Chi tiết -> Xuất ... Nó cũng được ẩn.
Siddhartha

9

Tôi đã giải quyết vấn đề này cho một nhà cung cấp chứng chỉ không phải là một phần của các máy chủ tin cậy JVM mặc định kể từ đó JDK 8u74. Nhà cung cấp là www.identrust.com , nhưng đó không phải là tên miền tôi đang cố gắng kết nối. Tên miền đó đã nhận được chứng chỉ từ nhà cung cấp này. Xem phần tin cậy gốc chéo có được liệt kê theo danh sách mặc định trong JDK / JRE không? - đọc một vài mục. Đồng thời xem những trình duyệt và hệ điều hành nào hỗ trợ Let Encrypt .

Vì vậy, để kết nối với tên miền mà tôi quan tâm, có chứng chỉ được cấp từ identrust.comtôi đã thực hiện các bước sau. Về cơ bản, tôi đã phải lấy DST Root CA X3chứng chỉ nhận dạng ( ) được JVM tin cậy. Tôi đã có thể làm điều đó bằng cách sử dụng Apache httpComponents 4.5 như vậy:

1: Nhận chứng chỉ từ sự không hài lòng tại Hướng dẫn tải xuống chuỗi chứng chỉ . Nhấp vào liên kết DST Root CA X3 .

2: Lưu chuỗi vào tệp có tên "DST Root CA X3.pem". Hãy chắc chắn để thêm các dòng "----- BEGIN CHỨNG NHẬN -----" và "----- CHỨNG NHẬN KẾT THÚC -----" trong tệp ở đầu và cuối.

3: Tạo tệp java keystore, cacerts.jks bằng lệnh sau:

keytool -import -v -trustcacerts -alias IdenTrust -keypass yourpassword -file dst_root_ca_x3.pem -keystore cacerts.jks -storepass yourpassword

4: Sao chép kho khóa cacerts.jks kết quả vào thư mục tài nguyên của ứng dụng java / (maven) của bạn.

5: Sử dụng đoạn mã sau để tải tệp này và đính kèm nó vào Apache 4.5 HttpClient. Điều này sẽ giải quyết vấn đề cho tất cả các miền có chứng chỉ được cấp từ indetrust.comorory bao gồm chứng chỉ vào kho khóa mặc định của JRE.

SSLContext sslcontext = SSLContexts.custom()
        .loadTrustMaterial(new File(CalRestClient.class.getResource("/cacerts.jks").getFile()), "yourpasword".toCharArray(),
                new TrustSelfSignedStrategy())
        .build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslcontext,
        new String[] { "TLSv1" },
        null,
        SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
        .setSSLSocketFactory(sslsf)
        .build();

Khi dự án xây dựng thì cacerts.jks sẽ được sao chép vào đường dẫn lớp và được tải từ đó. Tại thời điểm này, tôi đã không thử nghiệm các trang web ssl khác, nhưng nếu đoạn mã trên "chuỗi" trong chứng chỉ này thì chúng cũng sẽ hoạt động, nhưng một lần nữa, tôi không biết.

Tham khảo: Ngữ cảnh SSL tùy chỉnhLàm cách nào để tôi chấp nhận chứng chỉ tự ký với HttpsURLCconnectection của Java?


Câu hỏi là về một chứng chỉ tự ký. Câu trả lời này là không.
Hầu tước Lorne

4
Đọc câu hỏi (và trả lời) gần hơn một chút.
K.Nicholas

9

Apache HttpClient 4.5 hỗ trợ chấp nhận các chứng chỉ tự ký:

SSLContext sslContext = SSLContexts.custom()
    .loadTrustMaterial(new TrustSelfSignedStrategy())
    .build();
SSLConnectionSocketFactory socketFactory =
    new SSLConnectionSocketFactory(sslContext);
Registry<ConnectionSocketFactory> reg =
    RegistryBuilder.<ConnectionSocketFactory>create()
    .register("https", socketFactory)
    .build();
HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);        
CloseableHttpClient httpClient = HttpClients.custom()
    .setConnectionManager(cm)
    .build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse sslResponse = httpClient.execute(httpGet);

Điều này xây dựng một nhà máy ổ cắm SSL sẽ sử dụng TrustSelfSignedStrategy, đăng ký nó với trình quản lý kết nối tùy chỉnh sau đó thực hiện HTTP GET bằng trình quản lý kết nối đó.

Tôi đồng ý với những người ca tụng "không làm điều này trong sản xuất", tuy nhiên có những trường hợp sử dụng để chấp nhận chứng chỉ tự ký bên ngoài sản xuất; chúng tôi sử dụng chúng trong các thử nghiệm tích hợp tự động, do đó chúng tôi đang sử dụng SSL (như trong sản xuất) ngay cả khi không chạy trên phần cứng sản xuất.


6

Thay vì đặt nhà máy ổ cắm mặc định (IMO là một điều xấu) - yhis sẽ chỉ ảnh hưởng đến kết nối hiện tại chứ không phải mọi kết nối SSL bạn cố gắng mở:

URLConnection connection = url.openConnection();
    // JMD - this is a better way to do it that doesn't override the default SSL factory.
    if (connection instanceof HttpsURLConnection)
    {
        HttpsURLConnection conHttps = (HttpsURLConnection) connection;
        // Set up a Trust all manager
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
        {

            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return null;
            }

            public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
            {
            }

            public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
            {
            }
        } };

        // Get a new SSL context
        SSLContext sc = SSLContext.getInstance("TLSv1.2");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        // Set our connection to use this SSL context, with the "Trust all" manager in place.
        conHttps.setSSLSocketFactory(sc.getSocketFactory());
        // Also force it to trust all hosts
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // and set the hostname verifier.
        conHttps.setHostnameVerifier(allHostsValid);
    }
InputStream stream = connection.getInputStream();

2
Bạn checkServerTrustedkhông thực hiện logic cần thiết để thực sự tin tưởng chứng chỉ đảm bảo chứng chỉ không đáng tin cậy bị từ chối. Điều này có thể làm cho một số đọc tốt: Mã nguy hiểm nhất trên thế giới: xác nhận chứng chỉ SSL trong phần mềm không phải trình duyệt .
ngày

1
getAcceptedIssuers()Phương pháp của bạn không tuân thủ quy định cụ thể và 'giải pháp' này vẫn không an toàn triệt để.
Hầu tước Lorne

3

Có một cách khác tốt hơn để tin tưởng tất cả các chứng chỉ: Tạo một chứng chỉ TrustStoretin tưởng cụ thể vào một chứng chỉ nhất định và sử dụng chứng chỉ này để tạo một chứng chỉ để SSLContextlấy từ đó SSLSocketFactoryđể thiết lập HttpsURLConnection. Đây là mã hoàn chỉnh:

File crtFile = new File("server.crt");
Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(crtFile));

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("server", certificate);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());

Bạn có thể tải KeyStoretrực tiếp từ một tệp hoặc lấy Chứng chỉ X.509 từ bất kỳ nguồn đáng tin cậy nào.

Lưu ý rằng với mã này, các chứng chỉ trong cacertssẽ không được sử dụng. Điều này đặc biệt HttpsURLConnectionsẽ chỉ tin tưởng chứng chỉ cụ thể này.


1

Tin tưởng tất cả các chứng chỉ SSL: - Bạn có thể bỏ qua SSL nếu bạn muốn kiểm tra trên máy chủ thử nghiệm. Nhưng không sử dụng mã này cho sản xuất.

public static class NukeSSLCerts {
protected static final String TAG = "NukeSSLCerts";

public static void nuke() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { 
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] myTrustedAnchors = new X509Certificate[0];  
                    return myTrustedAnchors;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception e) { 
    }
}

}

Vui lòng gọi hàm này trong hàm onCreate () trong Hoạt động hoặc trong Lớp ứng dụng của bạn.

NukeSSLCerts.nuke();

Điều này có thể được sử dụng cho Volley trong Android.


Không hoàn toàn chắc chắn về lý do tại sao bạn bị bỏ phiếu, trừ khi mã không hoạt động. Có lẽ đó là giả định rằng Android có liên quan bằng cách nào đó khi câu hỏi ban đầu không gắn thẻ Android.
Lo-Tan

1

Câu trả lời được chấp nhận là tốt, nhưng tôi muốn thêm một cái gì đó vào đây vì tôi đang sử dụng IntelliJ trên Mac và không thể làm cho nó hoạt động bằng JAVA_HOMEbiến đường dẫn.

Hóa ra Java Home khác biệt khi chạy ứng dụng từ IntelliJ.

Để tìm ra chính xác vị trí của nó, bạn có thể làm System.getProperty("java.home")như đó là nơi các chứng chỉ tin cậy được đọc từ đó.


0

Nếu 'họ' đang sử dụng chứng chỉ tự ký, thì họ phải thực hiện các bước cần thiết để làm cho máy chủ của họ có thể sử dụng được. Cụ thể điều đó có nghĩa là cung cấp chứng chỉ của họ cho bạn ngoại tuyến một cách đáng tin cậy. Vì vậy, có được họ để làm điều đó. Sau đó, bạn nhập nó vào cửa hàng tin cậy của mình bằng cách sử dụng keytool như được mô tả trong Hướng dẫn tham khảo JSSE. Thậm chí đừng nghĩ về TrustManager không an toàn được đăng ở đây.

EDIT Vì lợi ích của mười bảy người (!), Và nhiều người bình luận bên dưới, những người rõ ràng không thực sự đọc những gì tôi đã viết ở đây, đây không phải là một trò đùa với các chứng chỉ tự ký. Không có gì sai với chứng chỉ tự ký khi được thực hiện chính xác. Nhưng, cách chính xác để thực hiện chúng là cung cấp chứng chỉ một cách an toàn thông qua quy trình ngoại tuyến, thay vì qua kênh không được xác thực mà chúng sẽ được sử dụng để xác thực. Chắc chắn điều này là hiển nhiên? Rõ ràng là rõ ràng đối với mọi tổ chức nhận thức về bảo mật mà tôi từng làm việc, từ các ngân hàng với hàng ngàn chi nhánh cho đến các công ty của riêng tôi. 'Giải pháp' cơ sở mã phía khách hàng tin tưởng tất cảcác chứng chỉ, bao gồm các chứng chỉ tự ký được ký bởi hoàn toàn bất kỳ ai, hoặc bất kỳ cơ quan độc lập nào tự thiết lập là CA, là thực tế không an toàn. Nó chỉ chơi ở an ninh. Nó là vô nghĩa. Bạn đang có một cuộc trò chuyện riêng tư, chống giả mạo, trả lời, chống tiêm chích với ... ai đó. Bất cứ ai. Một người đàn ông ở giữa. Một kẻ mạo danh. Bất cứ ai. Bạn cũng có thể chỉ sử dụng văn bản gốc.


2
Chỉ vì một số máy chủ quyết định sử dụng https, điều đó không có nghĩa là người có máy khách đưa ra những lời tào lao về bảo mật cho mục đích riêng của họ.
Gus

3
Tôi ngạc nhiên câu trả lời này đã bị hạ thấp rất nhiều. Tôi muốn hiểu thêm một chút tại sao. Có vẻ như EJP đang đề xuất rằng bạn không nên thực hiện tùy chọn 2 vì nó cho phép một lỗ hổng bảo mật lớn. Ai đó có thể giải thích tại sao (ngoài cài đặt trước khi triển khai) tại sao câu trả lời này có chất lượng thấp?
cr1pto

2
Chà, tôi đoán tất cả rồi. Gì "đó là tùy thuộc vào họ để thực hiện các bước cần thiết để làm cho máy chủ của họ có thể sử dụng" nghĩa là gì? Người vận hành máy chủ phải làm gì để có thể sử dụng được? Các bước bạn có trong tâm trí là gì? Bạn có thể cung cấp một danh sách của họ? Nhưng lùi về 1.000 feet, làm thế nào mà thậm chí còn liên quan đến vấn đề mà OP yêu cầu? Anh ta muốn biết làm thế nào để khách hàng chấp nhận chứng chỉ tự ký trong Java. Đó là một vấn đề đơn giản để trao niềm tin vào mã vì OP thấy chứng chỉ có thể chấp nhận được.
ngày

2
@EJP - Sửa lỗi cho tôi nếu tôi sai, nhưng chấp nhận chứng chỉ tự ký là quyết định chính sách của khách hàng. Nó không có gì để làm với các hoạt động phía máy chủ. Khách hàng phải đưa ra quyết định. Các chẵn lẻ phải làm việc cùng nhau để giải quyết vấn đề phân phối khóa, nhưng điều đó không liên quan gì đến việc làm cho máy chủ có thể sử dụng được.
ngày

3
@EJP - Tôi chắc chắn không nói, "tin tưởng tất cả các chứng chỉ" . Có lẽ tôi đang thiếu một cái gì đó (hoặc bạn đang đọc quá nhiều thứ) ... OP có chứng chỉ và được anh ấy chấp nhận. Anh ấy muốn biết làm thế nào để tin tưởng nó. Có lẽ tôi đang chia tóc, nhưng chứng chỉ không cần phải giao ngoại tuyến. Nên sử dụng xác minh ngoài băng tần, nhưng không giống như "phải được gửi đến máy khách ngoại tuyến" . Ông thậm chí còn có thể là cửa hàng sản xuất máy chủ và máy khách, vì vậy ông có điều kiện tiên quyết một tiên nghiệm kiến thức.
ngày


0

Thay vì sử dụng keytool như được đề xuất bởi nhận xét hàng đầu, trên RHEL, bạn có thể sử dụng update-ca-trust bắt đầu từ các phiên bản mới hơn của RHEL 6. Bạn sẽ cần phải có chứng chỉ ở định dạng pem. Sau đó

trust anchor <cert.pem>

Chỉnh sửa /etc/pki/ca-trust/source/cert.p11-kit và thay đổi "danh mục chứng chỉ: mục nhập khác" thành "danh mục chứng chỉ: thẩm quyền". (Hoặc sử dụng sed để làm điều này trong một kịch bản.) Sau đó làm

update-ca-trust

Một vài cảnh báo:

  • Tôi không thể tìm thấy "niềm tin" trên máy chủ RHEL 6 của mình và bạn không đề nghị cài đặt nó. Tôi đã kết thúc việc sử dụng nó trên máy chủ RHEL 7 và sao chép tệp .p11-kit qua.
  • Để làm việc này cho bạn, bạn có thể cần phải làm update-ca-trust enable. Điều này sẽ thay thế / etc / pki / java / cacerts bằng một liên kết tượng trưng chỉ đến / etc / pki / ca-trust / extract / java / cacerts. (Vì vậy, bạn có thể muốn sao lưu trước.)
  • Nếu ứng dụng khách java của bạn sử dụng các trích dẫn được lưu trữ ở một số vị trí khác, bạn sẽ muốn thay thế thủ công bằng một liên kết tượng trưng đến / etc / pki / ca-trust / extract / java / cacerts hoặc thay thế nó bằng tệp đó.

0

Tôi gặp vấn đề là tôi đã chuyển URL vào thư viện đang gọi url.openConnection();tôi đã điều chỉnh câu trả lời của jon-daniel,

public class TrustHostUrlStreamHandler extends URLStreamHandler {

    private static final Logger LOG = LoggerFactory.getLogger(TrustHostUrlStreamHandler.class);

    @Override
    protected URLConnection openConnection(final URL url) throws IOException {

        final URLConnection urlConnection = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()).openConnection();

        // adapated from
        // /programming/2893819/accept-servers-self-signed-ssl-certificate-in-java-client
        if (urlConnection instanceof HttpsURLConnection) {
            final HttpsURLConnection conHttps = (HttpsURLConnection) urlConnection;

            try {
                // Set up a Trust all manager
                final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    @Override
                    public void checkClientTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                    }

                    @Override
                    public void checkServerTrusted(final java.security.cert.X509Certificate[] certs, final String authType) {
                    }
                } };

                // Get a new SSL context
                final SSLContext sc = SSLContext.getInstance("TLSv1.2");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                // Set our connection to use this SSL context, with the "Trust all" manager in place.
                conHttps.setSSLSocketFactory(sc.getSocketFactory());
                // Also force it to trust all hosts
                final HostnameVerifier allHostsValid = new HostnameVerifier() {
                    @Override
                    public boolean verify(final String hostname, final SSLSession session) {
                        return true;
                    }
                };

                // and set the hostname verifier.
                conHttps.setHostnameVerifier(allHostsValid);

            } catch (final NoSuchAlgorithmException e) {
                LOG.warn("Failed to override URLConnection.", e);
            } catch (final KeyManagementException e) {
                LOG.warn("Failed to override URLConnection.", e);
            }

        } else {
            LOG.warn("Failed to override URLConnection. Incorrect type: {}", urlConnection.getClass().getName());
        }

        return urlConnection;
    }

}

Sử dụng lớp này có thể tạo một URL mới với:

trustedUrl = new URL(new URL(originalUrl), "", new TrustHostUrlStreamHandler());
trustedUrl.openConnection();

Điều này có lợi thế là nó được bản địa hóa và không thay thế mặc định URL.openConnection.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.