Java: SSL Clientside Authentication with self

I'm trying to secure a connection from a Java Client/Server application that communicates over the Internet. My idea was to use SSL sockets with self-signed certificates and client authentication. I did the following:

  • Server: Keystore containing new self-signed certificate. keytool -genkey -kelalg RSA ...
  • Client: Keystore containing new self-signed certificate. keytool -genkey -kelalg RSA ...
  • Server: Truststore containing exported client certificate (from bullet point above). keytool -export to export client certificate and keytool -import -v -trustcacerts to import it into the server's truststore
  • Client: Truststore containing exported server certificate (from first bullet point). keytool -export to export server certificate and keytool -import -v -trustcacerts to import it into the client's truststore
  • Trust- and keystores are attached correctly to the server/client. I can see the certificates being loaded (SSL debug information). But the whole thing doesn't work. During the SSL handshake, I get the following error (SSL debug information):

    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)
    

    When I disable client side authentication, it works flawlessly.

    I'd really appreciate some help. Thank you very much!

    Below you find the full, but anonymized output from the server:

    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)
    

    The first SSL trace appears to be part of the second one, displayed at the server. Please confirm.

    The second trace shows that the server asked for an RSA or DSS certificate signed by 'CN=xxxxxx Client, OU=communication, O=xxxxxx, L=Zuerich, ST=ZH, C=CH', and the client replied by sending an empty certificate chain. That can only mean either that the client's keystore doesn't have such a cert in it or that the client wasn't using the correct keystore.

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

    上一篇: 信托店vs钥匙店

    下一篇: Java:使用SSL进行SSL客户端身份验证