2013-08-22 30 views
23

Tôi đã gặp khó khăn trong gần một tuần để các ứng dụng của tôi chạy sau khi di chuyển các ứng dụng của tôi từ Windows 2000 sang Windows 2008 R2 Server.Xây dựng đường dẫn PKIX không thành công trong ứng dụng Java

Thủ tục:

  1. cài đặt Java JDK 1.7.0_25
  2. Set biến môi trường hệ thống JAVA_HOME-C:\Progra~1\Java\jdk1.7.0_25\
  3. nhập khẩu giấy chứng nhận vào cacerts với keytool
  4. Đảm bảo rằng chứng chỉ tồn tại trong keytool với -list.

Tôi đã cố gắng để lặp lại bước 3 với InstallCert để đảm bảo rằng i havent sai lầm bất cứ điều gì lên.

Các phương pháp trên không giải quyết vấn đề của tôi, vì vậy tôi đã cố gắng để làm điều đó cách lập trình:

System.setProperty("javax.net.ssl.trustStore", 
"C:/Progra~1/Java/jdk1.7.0_25/jre/lib/security/cacerts"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

Tuy nhiên không có bất kỳ may mắn. Tôi đang mắc kẹt và không hoàn toàn chắc chắn rằng hướng đi từ đây.

Stack trace:

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 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) 
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) 
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) 
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) 
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) 
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515) 
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) 
    at util.SMS.send(SMS.java:93) 
    at domain.ActivationSMSSenderMain.sendActivationMessagesToCustomers(ActivationSMSSenderMain.java:80) 
    at domain.ActivationSMSSenderMain.<init>(ActivationSMSSenderMain.java:44) 
    at domain.ActivationSMSSenderMain.main(ActivationSMSSenderMain.java:341) 
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) 
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) 
    at sun.security.validator.Validator.validate(Validator.java:260) 
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) 
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) 
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) 
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) 
    ... 14 more 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) 
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) 
    ... 20 more 

UPDATE:

Cả System.out.println(System.getProperty("javax.net.ssl.trustStore"));System.out.println(System.getProperty("javax.net.ssl.keyStore"));

lợi nhuận null.

+0

bạn đã thêm chứng chỉ trung gian của mình chưa? – happymeal

+0

Im không hoàn toàn chắc chắn rằng bạn có ý nghĩa, nhưng tôi đã không chạm vào các chứng chỉ mặc định trong cacerts. – JavaCake

+0

cert trung gian đề cập đến tổ chức phát hành chứng chỉ của bạn. nếu tổ chức phát hành chứng chỉ của bạn không đáng tin cậy, chứng chỉ của bạn cũng không đáng tin cậy. ví dụ: để xác thực google.com, bạn cũng sẽ cần phải thêm Google Internet Authority và GeoTrust vào truststore. – happymeal

Trả lời

22

Tôi chạy vào các vấn đề tương tự mà nguyên nhân và giải pháp hóa ra cả hai là khá đơn giản:

Nguyên nhân chính: Không import cert thích hợp sử dụng keytool

LƯU Ý: Chỉ có gốc nhập khẩu CA (hoặc riêng self-signed) giấy chứng nhận của bạn

Chú ý: không nhập một, không chứng chỉ gốc chuỗi trung gian cert

Solution Ví dụ cho imap.gmail.com

  1. Xác định cert CA gốc:

    openssl s_client -showcerts -connect imap.gmail.com:993 
    

    trong trường hợp này, chúng tôi tìm ra CA gốc là Equifax an toàn Certificate Authority

  2. Tải xuống root CA cert.
  3. Xác nhận cert tải về có đúng dấu vân tay SHA-1 và/hoặc MD5 bằng cách so sánh với thông tin found here
  4. nhập cert cho javax.net.ssl.trustStore:

    keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem 
    
  5. Chạy mã java của bạn
+3

Trong trường hợp bạn có nhiều JRE được cài đặt, bạn có thể chỉ định kho khóa bạn muốn nhập chứng chỉ thêm '-keystore path/to/jre/lib/security/cacerts' vào lệnh trong bước 4. –

0

Mỗi lần đăng ký trước, bạn cần phải thêm chứng chỉ proxy.tkk.com vào cửa hàng ủy thác.

+0

Bạn có biết cách tôi có thể truy xuất chứng chỉ cho proxy.tkk.com? Đây là proxy cục bộ. Tôi giả định rằng 'InstallCert' xử lý tất cả các phụ thuộc chứng chỉ. – JavaCake

+0

Nếu tất cả các kết nối của bạn đang trải qua proxy kiểm tra SSL, bạn sẽ cần chứng chỉ chung đang ký tất cả các chứng chỉ giả cho các trang web được truy cập. Điều này có thể được cài đặt trong các cửa hàng tin cậy của trình duyệt hoặc bạn có thể lấy nó từ quản trị viên proxy. Nếu bạn không thông qua proxy cho các kết nối này, bạn chỉ cần nhận chứng chỉ 'đúng' cho các trang web bạn đang cố gắng tin tưởng, có vẻ như được phát hành bởi RapidSSL chứ không phải proxy.tkk.com. Quản trị viên máy chủ có thể cung cấp những thứ này hoặc bạn có thể lấy chúng từ bên ngoài môi trường proxy. –

+0

Trong các ứng dụng dựa trên web khác của tôi không yêu cầu SSL tôi cần phải sử dụng tham số proxyHost để có quyền truy cập, nhưng điều đó là không đủ trong trường hợp này tôi giả định. – JavaCake

7

Bạn đã nhập chứng chỉ vào cửa hàng ủy thác của JRE được cung cấp trong JDK, nhưng bạn đang chạy java.exe của JRE được cài đặt trực tiếp.

EDIT

Để rõ ràng, và để giải quyết các bãi lầy của sự hiểu lầm trong các bài bình luận dưới đây, bạn cần phải nhập khẩu giấy chứng nhận vào cacerts tập tin của JRE bạn đang có ý định sử dụng, và ý chí hiếm khi bao giờ là một trong những vận chuyển bên trong JDK, bởi vì khách hàng thường sẽ không có một JDK. Bất cứ điều gì trong bình luận dưới đây cho thấy nếu không nên được bỏ qua như không thể hiện ý định của tôi ở đây.

Một giải pháp tốt hơn sẽ tạo ra riêng truststore của bạn, bắt đầu với một bản sao của tập tin cacerts, và đặc biệt là nói với Java để sử dụng một thông qua thuộc tính hệ thống javax.net.ssl.trustStore.

Bạn nên xây dựng phần này của quá trình xây dựng của bạn, để giữ cho đến ngày với những thay đổi tôi cacerts tập tin gây ra bởi nâng cấp JDK.

+0

Nhưng lỗi rõ ràng là một chứng chỉ còn thiếu, phải không? – JavaCake

+0

Có, vì bạn đã nhập chứng chỉ vào một cửa hàng tin cậy và bạn đang sử dụng một chứng chỉ khác. Đừng đọc câu trả lời. – EJP

+0

EJP, tôi nghĩ rằng tôi hiểu ngay bây giờ. Nhưng tôi đã cố gắng để khởi tạo các chứng chỉ vào 'cacerts' là tốt, mà không có bất kỳ sự khác biệt. – JavaCake

2

Nếu bạn đang sử dụng Eclipse chỉ cần kiểm tra chéo trong Eclipse Windows -> tùy chọn ----> java ---> JRE được cài đặt đang trỏ JRE hiện tại và JRE nơi yo u đã định cấu hình chứng chỉ của bạn. Nếu không xóa JRE và thêm jre nơi chứng chỉ của bạn được cài đặt