I am trying to get mutual SSL working from a Java client. My soapUI configuration works where I have specified keystore and truststore in WS-security configurations.
When I do the same with a Java client with the following system params
System.setProperty("javax.net.ssl.keyStore", "D:\\certs\\client_keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.debug", "all");
System.setProperty("javax.net.ssl.trustStore", "D:\\certs\\truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "trustpass");
I get this error
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed
connection during handshake
main, SEND TLSv1 ALERT: fatal, description = handshake_failure
Padded plaintext before ENCRYPTION: len = 18
I have enabled this: System.setProperty("javax.net.debug", "all");
From the debug logs I see this:
*** Certificate chain
***
How do I debug this issue?
Related
I have to read some emails in inbox from an email account. I need the TLSv1.2 like system update and when I send an email I can correctly do this but this methodology does not work when I have to read from the inbox folder.
Following my java code about connection preparation:
props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.pop3.socketFactory.port", Integer.valueOf(extProperties.getPortInbox().trim()));
props.put("mail.pop3.ssl.protocols", "TLSv1.2");
props.put("mail.pop3.starttls.enable", Boolean.TRUE);
props.put("mail.pop3.ssl.enable", Boolean.FALSE);
props.put("mail.mime.multipart.ignoreexistingboundaryparameter", Boolean.TRUE);
props.put("mail.mime.parameters.strict", Boolean.FALSE);
the params that I have are:
Protocol Type: POP3
Inbox server: (my server url)
Port: 995
I have this errors when I try to connect and read from the inbox folder:
...
(SimpleAsyncTaskExecutor-1) SimpleAsyncTaskExecutor-1, received EOFException: error
(SimpleAsyncTaskExecutor-1) SimpleAsyncTaskExecutor-1, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
(SimpleAsyncTaskExecutor-1) SimpleAsyncTaskExecutor-1, SEND TLSv1 ALERT: fatal, description = handshake_failure
(SimpleAsyncTaskExecutor-1) SimpleAsyncTaskExecutor-1, WRITE: TLSv1 Alert, length = 2
(SimpleAsyncTaskExecutor-1) SimpleAsyncTaskExecutor-1, called closeSocket()
...
In the log above, we can see the handshake error and the tlsv1 instead of the tlsv1.2 that I have setted.
How can I solve my problem? I have tried many ways found on stakoverflow/internet but I didn't resolve my problem and now I have no idea about the next step to do.
Thank you for the help
If I use the below in java.security (jdk 7 and even jdk 8) any update
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA,SHA,SHA1,SHA-1, DH keySize < 768
and I have no certificates in the chain that are sha signed certificates, I get the below exception:
main, handling exception: javax.net.ssl.SSLHandshakeException: Unsupported SignatureAndHashAlgorithm in ServerKeyExchange message
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
main, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
I am trying to disable using SHA/SHA1/SHA-1 as a message digest from the client side. Why do I get the above exception on SHA384.
If I remove the "SHAs" from the disabled algorithms in java.security all is fine.
Any ideas?
On server I've got a certificate which I am using to connect to other webservice.
Certificate is correctly installed on server, because when I am using curl to make a request, everything works fine. The problem is when I am using rest request through my webservice in Spring.
I've got exception:
handling exception: javax.net.ssl.SSLHandshakeException:
I was trying changing tls protocols and it didn't help.
What may cause the problem?
There is a code of a debugger:
https-jsse-nio-8080-exec-4, WRITE: TLSv1 Handshake, length = 120
https-jsse-nio-8080-exec-4, received EOFException: error
https-jsse-nio-8080-exec-4, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
https-jsse-nio-8080-exec-4, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
https-jsse-nio-8080-exec-4, WRITE: TLSv1.2 Alert, length = 2
https-jsse-nio-8080-exec-4, called closeSocket()
https-jsse-nio-8080-exec-4, called close()
https-jsse-nio-8080-exec-4, called closeInternal(true)
I'm building a java-ee application which should connect to an iCal CalDAV server using SSL.
I get this error every time I try to connect to the server.
javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
With other tools it worked fine, even with java tools after importing the certificate into the truststore.
If I try to connect using TLS I get a response that says, the server only supports SSLv3.
heres how I investigated the SSL handshake with the openssl tool
openssl s_client -host kalender.myserver.com -port 8443
this is what i get:
CONNECTED(00000003)
depth=2 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
1 s:/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
---
Server certificate
[[certificate]]
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
---
No client certificate CA names sent
---
SSL handshake has read 3422 bytes and written 565 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : SSLv3
Cipher : AES256-SHA
Session-ID: 99D28660004D122D20657883562319F4F3063B1123AC882AD722B781EB13FF45
Session-ID-ctx:
Master-Key: 6228C28941D81771C68F0FA5546491804081294A95F4A2BE19AC239CF47C24752AC350F54BAEDD3C8E4A7E1044B4B429
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1406820530
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
when i try
openssl s_client -tls1 -host kalender.myserver.com -port 8443
this appears and the connection fails:
CONNECTED(00000003)
139883471566496:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1407752794
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
Here's how I investigated the SSL handshake with a Java tool I found here.
I modified it so i can use another port.
to google:
java HTTPSClient google.com --> does not throw an exception
to my server on port 8443:
SSLv3: no error
TLSv1: javax.net.ssl.SSLHandshakeException: Server chose SSLv3, but that protocol version is not enabled or not supported by the client.
I drew the conclusion that the server only supports SSLv3, so I tried to get my app to do that too, using a HttpClient provided by apache but it does not seem to be compatible.
That means I have to say my app to use SSLv3, too. That would be somewhere in the org.osaf.caldav4j.methods.HttpClient class which inherits from org.apache.commons.httpclient.HttpClient. The problem is, I can't find any way to do so.
I tried
System.setProperty("https.protocols", "SSLv3");
and
httpClient.getParams().setParameter("https.protocols", "SSLv3");
but neither of them makes a difference. I also tried to somehow insert a custom SSLSocketFactory into the HTTPClient but found no way to do that. Here is the code to build the HTTPClient:
public HttpClient getHttpClient(String host, int port, String user, String password){
System.setProperty("https.protocols", "SSLv3");
org.apache.commons.httpclient.HttpClient httpClient = new HttpClient();
String protocol = "https";
String baseDir = "/calendars/users/" + user + "/calendar/";
httpClient.getHostConfiguration().setHost(host, port, protocol);
Credentials httpCredentials = new UsernamePasswordCredentials(user, password);
httpClient.getState().setCredentials(AuthScope.ANY, httpCredentials);
httpClient.getParams().setAuthenticationPreemptive(true);
httpClient.getParams().setParameter("https.protocols", "SSLv3");
return (HttpClient) httpClient;
}
And this is the stack trace i get when i try to connect (i cut off the java-ee internal stuff):
Caused by: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at org.apache.webdav.lib.methods.HttpRequestBodyMethodBase.writeRequestBody(HttpRequestBodyMethodBase.java:235)
at org.apache.webdav.lib.methods.XMLResponseMethodBase.writeRequestBody(XMLResponseMethodBase.java:303)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.osaf.caldav4j.methods.HttpClient.executeMethod(HttpClient.java:103)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
at org.osaf.caldav4j.CalDAVCollection.getCalDAVResources(CalDAVCollection.java:1029)
... 86 more
Problem solved with just one line of code.
System.setProperty("com.sun.net.ssl.rsaPreMasterSecretFix", "true");
If I understand it right, I need this to tell Java to use the maximum supported version of SSL/TLS instead of some weird other one. You can check it here. Anyways thanks for your help!
Java 7u9
Error msg in title is: "fatal error: 80: problem unwrapping net record". SO wouldn't let me put "problem" in the title.
I am building a Java HTTPS client against Netty. The SSL handshake was working until I added added the "HTTPS" endpoint identification algorithm to enable server hostname verification:
SSLEngine engine = tcpHelper.getSSLContext().createSSLEngine();
SSLParameters sslParameters = engine.getSSLParameters();
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
engine.setSSLParameters(sslParameters);
engine.setUseClientMode(true);
After adding the algorithm, the SSL handshake hangs and the connection eventually times out. With SSL debugging enabled (javax.net.debug=all), I can see that the handshake now fails after ServerHello, after the server sends it's cert chain, after
*** ServerHelloDone
1761586552#qtp-1653588482-2, WRITE: TLSv1.2 Handshake, length = 3294
on the server. The client receives and displays the cert chain, and then fails with:
New I/O worker #3, fatal error: 80: problem unwrapping net record
java.lang.RuntimeException: Delegated task threw Exception/Error
%% Invalidated: [Session-1, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
New I/O worker #3, SEND TLSv1.2 ALERT: fatal, description = internal_error
New I/O worker #3, WRITE: TLSv1.2 Alert, length = 2
Java 7u9
First, thanks to Bruno for his help on this related question which lead me to final answer.
Answering my own question. Hard won knowledge.
The solution is to add the host and port of the request target to the constructor when you create the SSL Engine:
SSLEngine engine = tcpHelper.getSSLContext().createSSLEngine(targetHost, targetPort);
Without this, Java will ultimately throw a NullPointerException way down deep in the SSL libs (IPAddressUtil.textToNumericFormatV4), which results in the not-very-helpful error message in the SSL debug output.