Search code examples
javasslsslhandshakeexception

Java SSL handshake failure - no client certificate


I am using a third party library with a build in ssl client to perform a CRL check on a PKCS#7 signature.

I have created a keystore and a truststore and put the server's CA in my truststore.

Looking to the debug below, the Cert Authorities and the Certificate chain are empty. My client didn't send back his certificate.

Could you explain what it's going on?

EDIT

Thanks to the comments below, I understood that the client's "empty CA" is not a problem.

The problem is that the server asks for a client certificate but my client doesn't send it to the server.

Why the client does not send his certificate ?

keyStore is : [...]
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
***
found key for : [...]
chain [0] = [
...
]
***
trustStore is: [...]
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
[...]

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
[...]
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(10000) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1445266954 bytes = { 44, 84, 229, 125, 84, 33, 145, 120, 170, 228, 77, 65, 146, 200, 227, 227, 48, 200, 116, 240, 140, 55, 227, 162, 119, 75, 116, 47 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: ...]
***
[write] MD5 and SHA1 hashes:  len = 176
[...]
main, WRITE: TLSv1 Handshake, length = 176
[Raw write]: length = 181
[...]
[Raw read]: length = 5
[...]
[Raw read]: length = 85
[...]
main, READ: TLSv1 Handshake, length = 85
*** ServerHello, TLSv1
RandomCookie:  GMT: 1929314415 bytes = { 133, 174, 213, 209, 239, 104, 185, 151, 182, 150, 87, 234, 171, 201, 244, 45, 171, 118, 159, 20, 148, 138, 19, 5, 1, 44, 188, 76 }
Session ID:  {144, 227, 198, 123, 46, 241, 49, 85, 156, 181, 102, 130, 42, 23, 39, 17, 11, 64, 23, 39, 166, 11, 119, 139, 12, 51, 60, 252, 170, 105, 23, 161}
Cipher Suite: SSL_RSA_WITH_3DES_EDE_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension server_name, server_name: 
***
%% Initialized:  [Session-1, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
** SSL_RSA_WITH_3DES_EDE_CBC_SHA
[read] MD5 and SHA1 hashes:  len = 85
[...]
[Raw read]: length = 5
[...]
[Raw read]: length = 1024
[...]
main, READ: TLSv1 Handshake, length = 1024
*** Certificate chain
chain [0] = [
[
 [...]
]
  Algorithm: [SHA1withRSA]
  Signature:
[...]

]
***
Found trusted certificate:
[
[...]
]
[read] MD5 and SHA1 hashes:  len = 1024
[...]
[Raw read]: length = 5
[...]
[Raw read]: length = 8
[...]
main, READ: TLSv1 Handshake, length = 8
*** CertificateRequest
Cert Types: RSA
Cert Authorities:
<Empty>
[read] MD5 and SHA1 hashes:  len = 8
[...]
[Raw read]: length = 5
[...]
[Raw read]: length = 4
[...]
main, READ: TLSv1 Handshake, length = 4
*** ServerHelloDone
[read] MD5 and SHA1 hashes:  len = 4
[...]
*** Certificate chain
***
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
[write] MD5 and SHA1 hashes:  len = 269
[...]
main, WRITE: TLSv1 Handshake, length = 269
[Raw write]: length = 274
[...]
SESSION KEYGEN:
PreMaster Secret:
[...]
CONNECTION KEYGEN:
Client Nonce:
[...]
Server Nonce:
[...]
Master Secret:
[...]
Client MAC write Secret:
[...]
Server MAC write Secret:
[...]
Client write key:
[...]
Server write key:
[...]
Client write IV:
[...]
Server write IV:
[...]
main, WRITE: TLSv1 Change Cipher Spec, length = 1
[Raw write]: length = 6
[...]
*** Finished
verify_data:  { 212, 27, 4, 13, 87, 128, 70, 120, 43, 97, 111, 135 }
***
[write] MD5 and SHA1 hashes:  len = 16
[...]
Padded plaintext before ENCRYPTION:  len = 40
[...]
main, WRITE: TLSv1 Handshake, length = 40
[Raw write]: length = 45
[...]
[Raw read]: length = 5
[...]
[Raw read]: length = 2
[...]
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, handshake_failure
%% Invalidated:  [Session-1, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Solution

  • I was missing the fact that the client's certificate has to be generated by the server via a Certificate Signing Request (CSR).

    The process is :

    1. Produce a keypair (via keytool -genkey)
    2. Generate a PKCS#10 CSR (via keytool -certreq)
    3. Send the CSR to the concerned authority
    4. Get back a SSL certificate

    Thanks for the comments that helped me to improve my ssl understanding.