Lỗi bắt tay có thể xảy ra do nhiều lý do:
- Các bộ mật mã không tương thích được sử dụng bởi máy khách và máy chủ. Điều này sẽ yêu cầu khách hàng sử dụng (hoặc kích hoạt) một bộ mật mã được máy chủ hỗ trợ.
- Các phiên bản SSL không tương thích đang sử dụng (máy chủ có thể chỉ chấp nhận TLS v1, trong khi máy khách chỉ có thể sử dụng SSL v3). Một lần nữa, khách hàng có thể phải đảm bảo rằng nó sử dụng phiên bản tương thích của giao thức SSL / TLS.
- Đường dẫn tin cậy không đầy đủ cho chứng chỉ máy chủ; chứng chỉ của máy chủ có thể không được khách hàng tin cậy. Điều này thường sẽ dẫn đến một lỗi dài dòng hơn, nhưng nó hoàn toàn có thể. Thông thường, cách khắc phục là nhập chứng chỉ CA của máy chủ vào kho ủy thác của khách hàng.
- Giấy chứng nhận được cấp cho một tên miền khác nhau. Một lần nữa, điều này sẽ dẫn đến một thông điệp dài dòng hơn, nhưng tôi sẽ nêu cách khắc phục ở đây trong trường hợp đây là nguyên nhân. Độ phân giải trong trường hợp này sẽ là lấy máy chủ (nó không có vẻ là của bạn) để sử dụng chứng chỉ chính xác.
Vì, lỗi cơ bản không thể được xác định chính xác, tốt hơn là bật -Djavax.net.debug=all
cờ để cho phép gỡ lỗi kết nối SSL được thiết lập. Khi gỡ lỗi được bật, bạn có thể xác định hoạt động nào trong quá trình bắt tay đã thất bại.
Cập nhật
Dựa trên các chi tiết hiện có, có vẻ như sự cố là do đường dẫn tin cậy chứng chỉ chưa hoàn chỉnh giữa chứng chỉ được cấp cho máy chủ và CA gốc. Trong hầu hết các trường hợp, điều này là do chứng chỉ CA gốc không có trong kho ủy thác, dẫn đến tình trạng không thể tồn tại đường dẫn tin cậy chứng chỉ; chứng chỉ về cơ bản là không tin cậy bởi khách hàng. Các trình duyệt có thể đưa ra cảnh báo để người dùng có thể bỏ qua điều này, nhưng điều tương tự không xảy ra đối với các máy khách SSL (như lớp HttpsURLConnection hoặc bất kỳ thư viện Máy khách HTTP nào như Máy khách HTTPComponents của Apache ).
Hầu hết các lớp / thư viện khách này sẽ dựa vào kho ủy thác được JVM sử dụng để xác thực chứng chỉ. Trong hầu hết các trường hợp, đây sẽ là cacerts
tệp trong thư mục JRE_HOME / lib / security. Nếu vị trí của cửa hàng tin cậy đã được chỉ định bằng cách sử dụng thuộc tính hệ thống JVM javax.net.ssl.trustStore
, thì cửa hàng trong đường dẫn đó thường là nơi được thư viện khách sử dụng. Nếu bạn nghi ngờ, hãy xem Merchant
lớp của bạn và tìm ra lớp / thư viện mà nó đang sử dụng để tạo kết nối.
Thêm CA cấp chứng chỉ của máy chủ vào cửa hàng ủy thác này phải giải quyết vấn đề. Bạn có thể tham khảo câu trả lời của tôi về một câu hỏi liên quan về việc nhận các công cụ cho mục đích này, nhưng tiện ích keytool Java là đủ cho mục đích này.
Cảnh báo : Cửa hàng ủy thác về cơ bản là danh sách tất cả các CA mà bạn tin tưởng. Nếu bạn đặt chứng chỉ không thuộc về CA mà bạn không tin tưởng, thì các kết nối SSL / TLS đến các trang web có chứng chỉ do thực thể đó cấp có thể được giải mã nếu khóa riêng có sẵn.
Cập nhật # 2: Tìm hiểu đầu ra của dấu vết JSSE
Kho khóa và kho ủy thác được JVM sử dụng thường được liệt kê ngay từ đầu, hơi giống như sau:
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: C:\Java\jdk1.6.0_21\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is :
Nếu kho tin sai được sử dụng, thì bạn sẽ cần nhập lại chứng chỉ của máy chủ sang đúng hoặc cấu hình lại máy chủ để sử dụng một chứng chỉ được liệt kê (không được khuyến nghị nếu bạn có nhiều JVM và tất cả chúng đều được sử dụng cho khác nhau nhu cầu).
Nếu bạn muốn xác minh xem danh sách các certs tin cậy có chứa các certs cần thiết hay không, thì có một phần tương tự, bắt đầu như sau:
adding as trusted cert:
Subject: CN=blah, O=blah, C=blah
Issuer: CN=biggerblah, O=biggerblah, C=biggerblah
Algorithm: RSA; Serial number: yadda
Valid from SomeDate until SomeDate
Bạn sẽ cần tìm nếu CA của máy chủ là một chủ đề.
Quá trình bắt tay sẽ có một vài mục nổi bật (bạn sẽ cần biết SSL để hiểu chi tiết về chúng, nhưng với mục đích gỡ lỗi cho vấn đề hiện tại, sẽ đủ để biết rằng một handshake_failure thường được báo cáo trong ServerHello.
1. Khách hàng
Một loạt các mục sẽ được báo cáo khi kết nối đang được khởi tạo. Tin nhắn đầu tiên được gửi bởi khách hàng trong thiết lập kết nối SSL / TLS là tin nhắn ClientHello, thường được báo cáo trong nhật ký là:
*** ClientHello, TLSv1
RandomCookie: GMT: 1291302508 bytes = { some byte array }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
Lưu ý các bộ mật mã được sử dụng. Điều này có thể phải đồng ý với mục trong tệp merchant.properIES của bạn, cho cùng một quy ước có thể được sử dụng bởi thư viện của ngân hàng. Nếu quy ước được sử dụng là khác nhau, không có lý do gì để lo lắng, vì ServerHello sẽ nêu rõ như vậy, nếu bộ mật mã không tương thích.
2. Máy chủ
Máy chủ phản hồi với ServerHello, điều đó sẽ cho biết liệu thiết lập kết nối có thể tiến hành hay không. Các mục trong nhật ký thường thuộc loại sau:
*** ServerHello, TLSv1
RandomCookie: GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***
Lưu ý bộ mật mã mà nó đã chọn; đây là bộ tốt nhất có sẵn cho cả máy chủ và máy khách. Thông thường bộ mật mã không được chỉ định nếu có lỗi. Chứng chỉ của máy chủ (và tùy chọn toàn bộ chuỗi) được gửi bởi máy chủ và sẽ được tìm thấy trong các mục dưới dạng:
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=server, O=server's org, L=server's location, ST =Server's state, C=Server's country
Signature Algorithm: SHA1withRSA, OID = some identifer
.... the rest of the certificate
***
Nếu xác minh chứng chỉ đã thành công, bạn sẽ tìm thấy một mục tương tự như:
Found trusted certificate:
[
[
Version: V1
Subject: OU=Server's CA, O="Server's CA's company name", C=CA's country
Signature Algorithm: SHA1withRSA, OID = some identifier
Một trong những bước trên sẽ không thành công, dẫn đến handshake_failure, vì việc bắt tay thường hoàn thành ở giai đoạn này (không thực sự, nhưng các giai đoạn bắt tay tiếp theo thường không gây ra lỗi bắt tay). Bạn sẽ cần phải tìm ra bước nào đã thất bại và đăng thông báo phù hợp dưới dạng cập nhật cho câu hỏi (trừ khi bạn đã hiểu thông điệp và bạn biết phải làm gì để giải quyết nó).