web-dev-qa-db-ja.com

Java:自己署名証明書によるSSLクライアントサイド認証

インターネット経由で通信するJavaクライアント/サーバーアプリケーションからの接続を保護しようとしています。私の考えは、自己署名証明書とクライアント認証でSSLソケットを使用することでした。次のようにしました:

  • サーバー:新しい自己署名証明書を含むキーストア。 keytool -genkey -kelalg RSA ...
  • クライアント:新しい自己署名証明書を含むキーストア。 keytool -genkey -kelalg RSA ...
  • サーバー:エクスポートされたクライアント証明書を含むトラストストア(上記の箇条書きから)。 keytool -exportはクライアント証明書をエクスポートし、keytool -import -v -trustcacertsをサーバーのトラストストアにインポートします
  • クライアント:(最初の箇条書きから)エクスポートされたサーバー証明書を含むトラストストア。 keytool -exportサーバー証明書をエクスポートし、keytool -import -v -trustcacertsクライアントのトラストストアにインポートします

信頼ストアとキーストアがサーバー/クライアントに正しく接続されています。読み込まれている証明書を確認できます(SSLデバッグ情報)。しかし、すべてがうまくいきません。 SSLハンドシェイク中に次のエラー(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)

クライアント側の認証を無効にすると、問題なく動作します。

私は本当にいくつかの助けに感謝します。どうもありがとうございました!

以下は、サーバーからの完全で匿名化された出力です。

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)
19
Chris

最初のSSLトレースは、2番目のSSLトレースの一部であるように見え、サーバーに表示されます。ご確認ください。

2番目のトレースは、サーバーがRSAまたはDSS 'CN = xxxxxx Client、OU = communication、O = xxxxxx、L = Zuerich、ST = ZH、C = CHによって署名された証明書を要求したことを示しています'、およびクライアントは空の証明書チェーンを送信して応答しました。これは、クライアントのキーストアにそのような証明書が含まれていないか、クライアントが正しいキーストアを使用していないことを意味します。

14
user207421