Bài đăng nổi bật

Hướng dẫn thay đổi thư mục root mặc định của Docker trên Linux

Hoàn cảnh: người viết gặp một trường hợp như này Được team hạ tầng cấp cho một máy chủ gồm 2 phân vùng lưu trữ, 1 phân vùng 20GB được gắn và...

13 tháng 11, 2012

Sử dụng kết nối SSL/TLS trên java với các self-certificate

Vấn đề này tôi gặp phải khi viết một unitest cho kết nối imaps tới một server sử dụng self-certificate. Mọi nỗ lực kết nối tới server tôi đều gặp lỗi java phàn nàn về việc kết nối sử dụng một certificate không đáng tin - "untrusted certificate". Câu hỏi đặt ra ở đây là làm thế nào để ép java tiếp tục sử dụng kết nối này?
Nếu bạn để ý mỗi khi bạn dùng trình duyệt để kết nối tới một địa chỉ dạng https:// nào đó bạn có thể nhận được thông báo về việc đây là một kết nối không đáng tin, nếu bạn tin tưởng nó thì có thể thêm ngoại lệ này vào trình duyệt. Và đây cũng là ý tưởng để tôi giải quyết vấn đề này, đó là tôi cần phải tìm cách để java sẽ tự động thêm certificate này vào kho lưu trữ của mình hoặc đánh lừa java để nó luôn luôn tin tưởng vào certificate này.
Cách làm như sau:
  • Trước khi mở kết nối tôi cho java chạy qua hàm sau:
    private static void disableUntrustedComplain(){
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers(){
                        return null;
                    }
                   
                    public void checkClientTrusted(X509Certificate[] certs, String authType){}
                   
                    public void checkServerTrusted(X509Certificate[] certs, String authType){}
                }
            };
            try{
                SSLContext sc = SSLContext.getInstance("TLS");//SSL nếu sử dụng mã hóa SSL.
                sc.init(null, trustAllCerts, new SecureRandom());
                SSLContext.setDefault(sc);
                System.out.println("disabled");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
  •  Hàm này có tác dụng giúp java bỏ qua các complaining về untrusted certificate
  • Sau khi chạy hàm này chúng ta có thể thoải mái kết nối tới bất kỳ một kết nối nào sử dụng SSL/TLS.
Vui lòng xem thêm tại đây để tham khảo:http://abhinavasblog.blogspot.com/2011/07/allow-untrusted-certificate-for-https.html 
UPDATE:
    Gần đây tôi có làm việc với các kết nối liên quan tới giao thức XMPP (cụ thể là với Openfire) thì thấy cần phải sửa đoạn code trên một chút thì mới chạy được (Lưu ý là chỉ áp dụng với Openfire thôi nhé).
    Khi xử lý kết nối với Openfire sử dụng các self-certificate, mặc dù tôi sử dụng hàm ở phía trên nhưng vẫn bị dính lỗi PKIX không tin tưởng certificate. Để xử lý lỗi này tôi làm như sau:
Khi khởi tạo kết nối tới server XMPP tôi thêm thông tin cấu hình như sau:
SSLContext sc = disableUntrustedComplain();
        ConnectionConfiguration cc = new ConnectionConfiguration("mydomain.com", 5222);
        cc.setCustomSSLContext(sc);
        XMPPConnection connection = new XMPPTCPConnection(cc);
Trong đó có một số điểm lưu ý:
  • Hàm disableUntrustedComplain tôi trả về một giá trị thay vì sử dụng void như ở trên.
    Hàm này nội dung sẽ như sau:
    private static SSLContext disableUntrustedComplain(){
            SSLContext sc = null;
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {

                    @Override
                    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                }
            };
            //install the all-trusting trust manager
            try {
                sc = SSLContext.getInstance("TLS");//TLS or SSL
                sc.init(null, trustAllCerts, new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                SSLContext.setDefault(sc);
                System.out.println("disable");
            } catch(NoSuchAlgorithmException naex){
                naex.printStackTrace();
            }catch(KeyManagementException kmex){
                kmex.printStackTrace();
            }finally{
                return sc;
            }
        }

Không có nhận xét nào:

Đăng nhận xét