Một 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 giấy chứng nhận để 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 để kết nối với máy chủ thành công.
Đây là 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 nào cho chứng chỉ tự ký, điều này sẽ chết tạ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 là mã của tôi cần dạy Java chấp nhận chứng chỉ tự ký này, cho một vị trí này trong ứng dụng và không ở đâu khác.
Tôi biết rằng tôi có thể nhập chứng chỉ vào kho ủy quyền chứng chỉ của JRE và điều đó sẽ cho phép Java chấp nhận nó. Đó không phải là một cách tiếp cận tôi muốn thực hiện nếu tôi có thể giúp đỡ; có vẻ như rất xâm lấn để thực hiện trên tất cả các máy của khách hàng của chúng tôi cho một mô-đun mà họ không thể sử dụng; nó sẽ ảnh hưởng đến tất cả các ứng dụng Java khác sử dụng cùng một JRE và tôi không thích điều đó mặc dù tỷ lệ của bất kỳ ứng dụng Java nào khác từng truy cập trang web này là không. Đây 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 một TrustManager ủy thác cho TrustManager thực sự 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 rằng 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 đó cũng không đúng với tôi.
Cách ưa thích, tiêu chuẩn hoặc cách 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 tôi có trong đầu, hoặc tôi sẽ phải thỏa hiệp? Có một tùy chọn liên quan đến các tập tin và thư mục và cài đặt cấu hình, và ít mã không?