Mô-đun tôi đang thêm vào ứng dụng Java lớn của chúng tôi phải trò chuyện với trang web được bảo mật SSL của một công ty khác. Vấn đề là trang web sử dụng chứng chỉ tự ký. Tôi có một bản sao của chứng chỉ để xác minh rằng tôi không gặp phải một cuộc tấn công trung gian, và tôi cần kết hợp chứng chỉ này vào mã của chúng tôi sao cho kết nối với máy chủ sẽ thành công.Tôi làm cách nào để sử dụng các chứng chỉ khác nhau trên các kết nối cụ thể?
Dưới đây là các mã cơ bản:
void sendRequest(String dataPacket) {
String urlStr = "https://host.example.com/";
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setMethod("POST");
conn.setRequestProperty("Content-Length", data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
o.write(data);
o.flush();
}
Nếu không có bất kỳ xử lý bổ sung tại chỗ cho các chứng chỉ tự ký, điều này qua đời ở tuổi conn.getOutputStream() với ngoại lệ sau:
Exception in thread "main" 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
....
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
....
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Lý tưởng nhất , mã của tôi cần dạy Java chấp nhận chứng chỉ tự ký này, cho một điểm này trong ứng dụng, và không nơi nào khác.
Tôi biết rằng tôi có thể nhập chứng chỉ vào kho lưu trữ chứng chỉ của JRE và điều đó sẽ cho phép Java chấp nhận nó. Đó không phải là cách tiếp cận tôi muốn thực hiện nếu tôi có thể giúp; nó có vẻ rất xâm lấn để làm trên tất cả các máy khách hàng của chúng tôi cho một mô-đun mà họ có thể không sử dụng; nó sẽ ảnh hưởng đến tất cả các ứng dụng Java khác bằng cách sử dụng cùng một JRE và tôi không thích điều đó mặc dù tỷ lệ cược của bất kỳ ứng dụng Java nào khác từng truy cập vào trang web này là không. Nó cũng không phải là một hoạt động tầm thường: trên UNIX tôi phải có quyền truy cập để sửa đổi JRE theo cách này.
Tôi cũng thấy rằng tôi có thể tạo một cá thể TrustManager thực hiện một số kiểm tra tùy chỉnh. Có vẻ như tôi thậm chí có thể tạo ra một TrustManager ủy nhiệm cho TrustManager thực trong tất cả các trường hợp ngoại trừ một chứng chỉ này. Nhưng có vẻ như TrustManager được cài đặt trên toàn cầu, và tôi cho là sẽ ảnh hưởng đến tất cả các kết nối khác từ ứng dụng của chúng tôi, và điều đó không có mùi hoàn toàn đúng với tôi.
Cách ưa thích, tiêu chuẩn hoặc tốt nhất để thiết lập ứng dụng Java để chấp nhận chứng chỉ tự ký là gì? Tôi có thể hoàn thành tất cả các mục tiêu mà tôi có trong đầu, hay tôi sẽ phải thỏa hiệp? Có tùy chọn nào liên quan đến tệp và thư mục cũng như cài đặt cấu hình và mã không có không?
sửa lỗi nhỏ, đang hoạt động: http://www.rgagnon.com/javadetails/java-fix-certificate-problem-in-HTTPS.html –
@Hasenpriester: vui lòng không đề xuất trang này. Nó vô hiệu hóa tất cả xác minh tin cậy. Bạn không chỉ chấp nhận chứng chỉ tự ký mà bạn muốn, bạn cũng chấp nhận bất kỳ chứng chỉ nào mà kẻ tấn công MITM sẽ giới thiệu cho bạn. – Bruno