Java:使用SSL进行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)
    

    第一个SSL跟踪似乎是第二个SSL跟踪的一部分,显示在服务器上。 请确认。

    第二个跟踪显示服务器要求提供由'CN = xxxxxx客户端,OU =通信,O = xxxxxx,L = Zuerich,ST = ZH,C = CH'签署的RSA或DSS证书,客户通过发送空的证书链。 这只能意味着客户的密钥库中没有这样的证书,或者客户端没有使用正确的密钥库。

    链接地址: http://www.djcxy.com/p/21831.html

    上一篇: Java: SSL Clientside Authentication with self

    下一篇: signed ssl certificate in Java client