I have a Java client which is using the Apache HttpClient 4.1 library to make an HTTPs request to a server which doesn't require authentication. If I call that server with my browser or curl, the request is accepted. However from my Java client, I see the following (when debug is turned on)...
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
main, handling exception: java.net.SocketException: Connection reset
So it seems my client did the handshake in TLSv1 but then sent an SSLv2 ClientHello which the server didn't seem to like. According to this post it seems the server should not reject an SSLv2 ClientHello. Could it be something specific about this server that is making it reject this ClientHello?
I also noticed the below log output at the beginning of establishing the connection....
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/cacerts
trustStore type is : jks
trustStore provider is :
init truststore
adding as trusted cert:
Subject: CN=Secure Global CA, O=SecureTrust Corporation, C=US
And then it goes on to add various entities as "trusted cert"s.
And the final exception I noticed was...
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
So could it be a problem with the certificate (or lack of) on my (client) side? But according to this post I thought the client was not required to provide a certificate.
Bottom line is I am not clear if the root of the problem is the SSLv2 Client Hello or the certs or both?
I had a similar problem like you. This is how I solved it. It may not cater to your exact problem, but give it a try.
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
Related
My application invokes a web service request. The provider of this web service is requesting for a certificate based authentication.
Unfortunately while making the handshake, the certificate is not being returned as part of the CertificateRequest step. Below is the log trace
Cert Authorities:
<Empty>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client
authentication
I have placed the keystore and the truststore using the below properties which is being picked up during the handshake (logged in the logs)
-Djavax.net.ssl.keyStore=$CMX_SSL_KEY_STORE
-Djavax.net.ssl.keyStorePassword=123456
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=pkcs12
JAVA_OPTS= JAVA_OPTS="-D$PS_TOKEN$ENV_TOKEN $LOCAL_MEM_OPTS $GC_OPTS
$CMAX_OPTS $JMX_OPTS $CMX_SSL_TRUST_STORE_OPT $MQ_OPTS
$ADDITIONAL_JVM_OPTS $LOCAL_JVM_OPTS $CMX_SSL_KEY_STORE_OPT"
I don't have a private key as part of the keystore, as the vendor who provided the certificate refused to provide the private key. As part of the keystore, I have the whole chain of the certificate, but still its not working
Error seen in the logs is as below
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
Need some guidance to resolve this issue
I looked at
why doesn't java send the client certificate during SSL handshake?
which is on the same problem, but the solution provided by Bruno is failing. Not able to attach the certificate to the private key using the same alias
I don't have a private key as part of the keystore
Then you don't have a keystore: you have a truststore.
as the vendor who provided the certificate refused to provide the private key.
Of course he did. None of your beeswax.
You're supposed to provide your own private key and certificate in your own keystore.
You have a serious misunderstanding here.
I have a Go program that uses tls.Server to accept TLS connections from clients. When a particular client connects, I'm getting the error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority".
I'd like to see the certificate chain that was presented (and failed to verify) so that I can figure out what the client is doing wrong. Is there a way to do that using Go's tls package? The obvious answer - to use the ConnectionState method - doesn't work because the ConnectionState's PeerCertificates field is only populated after the handshake has completed successfully.
So far, I've used openssl, sslyze, keystore utilities, and some of the standard Windows diagnostics commands to try and characterize this problem. The summary is that as soon as I attempt to use a keystore that has the CA signed certificate in it, I get an immediate handshake failure 40 after the client hello. The connection never gets as far as a server hello with the CA cert in place.
On the same machine (Windows Server 2012), if I use a self signed certificate, the connection works as expected.
Openssl shows the handshake failure with the CA certificate in place.
sslyze shows all ciphers rejected with either no ciphers available or TLS / Alert handshake failure.
The fact that this is successful with a self-signed certificate tends to indicate that the "basics" are there, that the client and server have the necessary ciphers and so on to connect, and that server.xml is configured properly.
There were no error messages when importing the certificates, and everything seems to be configured correctly with the CA certs based on keytool checks. There are no error messages given during server start to indicate any problems processing the certificate.
Is there something I should be looking more closely at in regards to the keystore with the CA cert that could cause this complete rejection of the client hello? How would a different keystore or CA certs within aaffect the earliest steps of the handshake?
Thank you for information provided.
I assume that you are talking about a server side certificate and a server side key store, since the error happens at a state where no client certificates are yet involved. If the server is able to send the self-signed certificate to the client, but is not able to send the CA signed certificate to the client, then it must be something wrong with the certificate you are trying to send or that the certificate can not be used together with the ciphers offered by the client.
Since the problem is obviously on the server side you should first check all logs written on the server side for hints what the error might be. Typical problems are non-existing files, wrong files, password protected client key w/o providing a password or that the key does not belong to the certificate.
The question is very clear but I did not find any useful tutorial online. So I wish I could have some luck here.
Basically, I want to build a client certificate authentication with Apache. I configured the conf file for Apache for the site I am hosting. The conf I put is here:
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/apache2/ssl/client.crt
However I have no idea how to generate the certificate and key file for the client. And also, what file should I put on the SSLCACertificateFile in the Apache server configurations?
Does the server simply compare the certificate file sent from client with the certificate file on the server? What exactly the client certificate authentication is doing ?
You'll find instructions on how to create a CA cert and certs signed by this CA cert here:
http://pages.cs.wisc.edu/~zmiller/ca-howto/
Things go like this:
you setup your root CA key and cert
client generates his private key and certificate request
they send you the certificate request
you generate the certificate using the certificate request, your root CA cert and root CA key
you return the certificate to the client
You can then check that the client presents a certificate which is "signed" by the CA.
It is important to understand SSLVerifyClient and the other directives.
From Practical Issues with TLS Client Certificate
Authentication (page 3):
The default value none of SSLVerifyClient does
not require CCA; therefore the server will not include a
CertificateRequest message in the TLS handshake.
The value require will require CCA, and thus the
CertificateRequest message will be included in the
handshake. If the client does not provide any certificate in
the client’s Certificate message or mod_ssl fails to
verify the certificate provided, the TLS handshake will be
aborted and a fatal TLS alert message will be sent to the
client.
The value optional is the same as require, but
an empty client’s Certificate message will be tolerated.
The last possible value optional_no_ca is the same as
optional, but in addition it allows a client’s certificate to be
submitted that does not chain up to the CA trusted by the server
(because of a bug in OpenSSL [6] not yet valid or expired
non-self-signed client certificates will also be accepted).
The
value optional_no_ca can be used to perform certificate
verification at an application level or to implement PKI-less
public-key authentication that uses X.509 certificates as a
public-key transport.
I'm using Java 8, Netty 5 Alpha.
I added the certificates from Comodo to the keystore, and according to a test website suggested by my certificate provider they are installed correctly.
But if I try to connect using Firefox, Chrome, or curl, I get errors.
From curl -v I see that it gets the correct header, but then SSLv3, TLS alert, Server hello (2):. This seems to correspond with debug messages from Java:
SEND TLSv1.2 ALERT: warning, description = close_notify
WRITE: TLSv1.2 Alert, length = 32
fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
Firefox: SSL received a record that exceeded the maximum permissible length.
From openssl s_client -connect ...:
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-DES-CBC3-SHA
verify error:num=19:self signed certificate in certificate chain
SSL handshake has read 5982 bytes and written 531 bytes
I've read elsewhere about NullPointerExceptions somewhere causing internal Java security stuff to fail. But there's no clear solutions.