2010-12-12 50 views
18

Tôi đang cố gắng bảo mật kết nối từ ứng dụng Java Client/Server giao tiếp qua Internet. Ý tưởng của tôi là sử dụng ổ cắm SSL với chứng chỉ tự ký và xác thực ứng dụng khách. Tôi đã làm như sau:Java: Xác thực SSL Clientside với chứng chỉ tự ký

  • Máy chủ: Keystore chứa chứng chỉ tự ký mới. keytool -genkey -kelalg RSA ...
  • Khách hàng: Keystore chứa chứng chỉ tự ký mới. keytool -genkey -kelalg RSA ...
  • Máy chủ: Truststore chứa chứng chỉ ứng dụng khách đã xuất (từ điểm dấu đầu dòng). keytool -export để xuất chứng chỉ ứng dụng khách và keytool -import -v -trustcacerts để nhập chứng chỉ đó vào cửa hàng ủy thác của máy chủ
  • Khách hàng: Truststore chứa chứng chỉ máy chủ xuất (từ điểm dấu đầu tiên). keytool -export để xuất chứng chỉ máy chủ và keytool -import -v -trustcacerts để nhập chứng chỉ đó vào cửa hàng ủy thác của khách hàng

Trust- và keystores được đính kèm chính xác vào máy chủ/khách hàng. Tôi có thể thấy các chứng chỉ đang được tải (thông tin gỡ lỗi SSL). Nhưng toàn bộ mọi thứ không hoạt động. Trong quá trình bắt tay SSL, tôi nhận được lỗi sau (thông tin gỡ lỗi SSL):

main, WRITE: TLSv1 Handshake, length = 897 
main, READ: TLSv1 Handshake, length = 141 
*** Certificate chain 
*** 
main, SEND TLSv1 ALERT: fatal, description = bad_certificate 
main, WRITE: TLSv1 Alert, length = 2 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: null cert chain 
main, IOException in getSession(): javax.net.ssl.SSLHandshakeException: null cert chain 
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificateChain(Unknown Source) 
    at sslsocket.Server.getClientDistinguishedName(Server.java:86) 
    at sslsocket.Server.main(Server.java:37) 

Khi tôi vô hiệu hóa xác thực phía máy khách, nó hoạt động hoàn hảo.

Tôi thực sự đánh giá cao một số trợ giúp. Cảm ơn nhiều!

Dưới đây bạn tìm thấy đầy đủ, nhưng sản lượng ẩn danh từ máy chủ:

Initializing SSL 
*** 
found key for : server 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 

    Key: Sun RSA public key, 1024 bits 
    modulus: 9487726xxxxxx15617628447913191 
    public exponent: 65537 
    Validity: [From: Thu Dec 09 17:04:05 CET 2010, 
       To: Wed Jul 03 18:04:05 CEST 2109] 
    Issuer: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    SerialNumber: [ 4dxxxxxx5] 

] 
    Algorithm: [SHA1withRSA] 
    Signature: 
0000: 6F 06 1D EA E9 DC 5B 5D EC EB 33 D4 47 01 94 1A o.....[]..3.G... 
xxxxxx 
0070: 99 78 C4 31 5F 84 8F 7B C1 2F 10 A1 9F 50 72 A1 .x.1_..../...Pr. 

] 
*** 
adding as trusted cert: 
    Subject: CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Issuer: CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Algorithm: RSA; Serial number: 0x4xxxxxx0 
    Valid from Thu Dec 09 17:06:56 CET 2010 until Wed Jul 03 18:06:56 CEST 2109 

trigger seeding of SecureRandom 
done seeding SecureRandom 
Opening socket 
Waiting for clients... 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
matching alias: server 
main, called closeSocket() 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
[read] MD5 and SHA1 hashes: len = 3 
0000: 01 03 01           ... 
[read] MD5 and SHA1 hashes: len = 98 
0000: 00 3C 00 00 00 20 00 00 04 01 00 80 00 00 05 00 .<... .......... 
xxxxxx 
0060: 26 51            &Q 
main, READ: SSL v2, contentType = Handshake, translated length = 75 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1292088238 bytes = { 223,xxxxxx, 81 } 
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, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
*** 
%% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5] 
*** ServerHello, TLSv1 
RandomCookie: GMT: 1292088238 bytes = { 222,xxxxxx, 241 } 
Session ID: {77,xxxxxx, 235} 
Cipher Suite: SSL_RSA_WITH_RC4_128_MD5 
Compression Method: 0 
Extension renegotiation_info, renegotiated_connection: <empty> 
*** 
Cipher suite: SSL_RSA_WITH_RC4_128_MD5 
*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 

    Key: Sun RSA public key, 1024 bits 
    modulus: 948772xxxxxx17628447913191 
    public exponent: 65537 
    Validity: [From: Thu Dec 09 17:04:05 CET 2010, 
       To: Wed Jul 03 18:04:05 CEST 2109] 
    Issuer: CN=xxxxxx Server, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH 
    SerialNumber: [ 4d00fdf5] 

] 
    Algorithm: [SHA1withRSA] 
    Signature: 
0000: 6F 06 1D EA E9 DC 5B 5D EC EB 33 D4 47 01 94 1A o.....[]..3.G... 
xxxxxx 
0070: 99 78 C4 31 5F 84 8F 7B C1 2F 10 A1 9F 50 72 A1 .x.1_..../...Pr. 

] 
*** 
*** CertificateRequest 
Cert Types: RSA, DSS 
Cert Authorities: 
<CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH> 
*** ServerHelloDone 
[write] MD5 and SHA1 hashes: len = 897 
0000: 02 00 00 4D 03 01 4D 04 B4 AE DE E4 AF 62 FA 48 ...M..M......b.H 
0xxxxxx 
0380: 00             . 
main, WRITE: TLSv1 Handshake, length = 897 
main, READ: TLSv1 Handshake, length = 141 
*** Certificate chain 
*** 
main, SEND TLSv1 ALERT: fatal, description = bad_certificate 
main, WRITE: TLSv1 Alert, length = 2 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: null cert chain 
main, IOException in getSession(): javax.net.ssl.SSLHandshakeException: null cert chain 
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificateChain(Unknown Source) 
    at sslsocket.Server.getClientDistinguishedName(Server.java:86) 
    at sslsocket.Server.main(Server.java:37) 
+0

Điều gì sẽ xảy ra nếu bạn thêm chứng chỉ tự ký của khách hàng vào kho tin cậy của chính mình? –

+0

Không tạo ra bất kỳ sự khác biệt nào. Tôi vẫn gặp lỗi tương tự. – Chris

+0

Nó hoạt động cho tôi nếu máy chủ của tôi có chứa chứng chỉ máy khách và cửa hàng tin cậy của khách hàng của tôi chứa chứng chỉ máy chủ. –

Trả lời

14

Các dấu vết SSL đầu tiên dường như là một phần của một giây, hiển thị ở máy chủ. Vui lòng xác nhận.

Dấu vết thứ hai cho thấy máy chủ đã yêu cầu chứng chỉ RSA hoặc DSS được ký bởi 'CN = xxxxxx Khách hàng, OU = thông tin liên lạc, O = xxxxxx, L = Zuerich, ST = ZH, C = CH' và khách hàng đã trả lời bằng cách gửi một chuỗi chứng chỉ trống. Điều đó chỉ có thể có nghĩa là kho khóa của khách hàng không có chứng chỉ đó hoặc máy khách không sử dụng kho khóa chính xác.

+0

Cảm ơn câu trả lời đó. Tôi kiểm tra lại keystore của khách hàng, mặc dù tôi đã nghĩ rằng tôi đã làm điều này 100 lần. Dù sao, tôi nhận thấy rằng keystore chỉ chứa khóa công khai chứ không phải khóa cá nhân của chứng chỉ của ứng dụng khách. Bằng cách nào đó tôi phải có sai lầm. – Chris

+0

Điều này rất hữu ích, nó đã làm rõ rằng chứng chỉ CA đã ký hoặc khóa riêng hoặc toàn bộ kho khóa đã bị thiếu trong quá trình này không thành công tại điểm này '*** Chuỗi chứng chỉ' ... Đối với tôi, vấn đề là' SSLSocketFactory.getSocketFactory() 'tự động tải bộ truststore bằng' -Djavax.net.ssl.trustStore' nhưng nó KHÔNG tự động tải kho khóa được thiết lập bởi '-Djavax.net.ssl.keyStore' !! Vì vậy, tôi phải làm điều này một cách rõ ràng: http://www.smartjava.org/content/client-certificates-httpclient-4 – pulkitsinghal

+2

Chỉ SSLContext mặc định tuân theo javax.ney.ssl.keyStore. Những người bạn xây dựng cho mình với getInstance() không vì lý do nào. – EJP

Các vấn đề liên quan