LDAPS : Simple bind failed - java

I'm facing issue connecting to LDAPS from my application. I have imported all necessary certificates on JRE keystore.
I'm able to make calls to LDAPs when I put the following string in java.security
jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
When I change this line to
jdk.tls.disabledAlgorithms=MD5, DSA, DESede, DES_CBC, DHE, RC4, SSLv3, ECDH_anon, DH_anon, NULL, DH keySize < 768, RSA keySize < 2048
my connection fails with following error:
Caused by: javax.naming.CommunicationException: simple bind failed: testxxxxl.xxxx.com:636 [Root exception is java.net.SocketException: Socket closed]
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:218)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2740)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:316)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:211)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
at org.jboss.as.naming.InitialContext.getDefaultInitCtx(InitialContext.java:122)
... 72 more
Caused by: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:709)
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 com.sun.jndi.ldap.Connection.writeRequest(Connection.java:431)
at com.sun.jndi.ldap.Connection.writeRequest(Connection.java:404)
at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:358)
In wireshark it complains about certificate invalid.My question is if my certificate is invalid, it shouldn't be working with this line as well.
jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
Please help me to solve the issue.

If you use a secure connection to the LDAP server and you see an error like the following when trying to connect to Active Directory:
simple bind failed: ad.hostname.com:636
Import the LDAP server public certificate directly into the Klocwork keystore (which should be_jvm\lib\security\cacerts).
This causes the certificate validation process at the Klocwork end to be bypassed, since you have decided to trust the LDAP server certificate by importing it into your list of trusted certificates.
Ask your LDAP administrator to set this extension of your LDAP server certificate to non-critical.

In recent versions of Java the TLSv1 has been disabled.
In my case this happened when upgrading from Java 8 to Java 11.
Re-enabling TLSv1 helped. It is as easy as defining property:
-Djdk.tls.client.protocols=TLSv1
Of course you can need also other protocols, so you can specify full list:
-Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2,TLSv1.3

Related

Default Mysql SSL connection faling after overriding default kaystore to custom keystore

I have Mysql 8.0.19 as docker instance.
In our application previously we use JDK's default keystore for SSL.
With JDK's keystore connection to Mysql server is just fine with SSL and without SSL.
Here we didnt configured the SSL for Mysql manually. We are using default SSL mechanism of Mysql.
Now for some reason we decided to use our own keystore and to use that we overrided the keystore for JVM with below variables
-Djavax.net.ssl.keyStore=$keystorePath$
-Djavax.net.ssl.keyStorePassword=$sslKeyStorePwd$
-Djavax.net.ssl.trustStore=$keystorePath$"
-Djavax.net.ssl.trustStorePassword=$sslKeyStorePwd$
Now after this, connection to mysql for SSL is faling with below errors
javax.net.ssl|ERROR|01|main|2021-08-10 16:20:30.019 IST|TransportContext.java:313|Fatal (UNKNOWN_CA): Received fatal alert: unknown_ca (
"throwable" : {
javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
Exception in thread "main" com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
In /var/lib/mysql/ we have
ca.pem,ca-key.pem,client-cert.pem,client-key.pem, public_key.pem,private_key.pem,server-cert.pem, server-key.pem.
To resolve this error I tried to import the ca.pem,client-cert.pem, server-cert.pem into our keystore but it didnt worked.
unknown_ca means that the certificate was not signed by a trusted Certificate Authority. My guess is that you do not have the whole chain in your keystore

Java MySQL SSL connection with specified cert

I am trying to make a Java application which uses jdbc (Connector/J) to connect to a mariadb database using SSL encryption.
I already created a self signed certificate a configured the server to use it.
When I try to connect I get an exception because the certificate isn't trusted because it was self signed and not added to the Java trust store.
Because I want to modify the TrustStore or use a different one for my application I searched for a way to tell only jdbc which cert is trusted, and found "https://mariadb.com/kb/en/library/using-tlsssl-with-mariadb-connectorj/ Provide Certificate directly"
When I now try to connect with:
DriverManager.getConnection("jdbc:mysql://<hostname>:3306/<database>?useSSL=true&requireSSL=true&serverSslCert=/tmp/ssl/server-cert.pem", "<username>", "<password>");
I get this exception which I already got before not using the serverSslCert parameter again:
Exception in thread "main"
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 136 milliseconds ago. The last packet sent successfully to the server was 129 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:203)
at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4901)
at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1659)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1226)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2188)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2219)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2014)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:776)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:386)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)
at gymcash.server.mysql.DriverWrapper.connect(DriverWrapper.java:22)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at gymcash.server.mysql.MySQL.connect(MySQL.java:48)
at gymcash.server.mysql.MySQL.connect(MySQL.java:52)
at gymcash.server.main.Main.main(Main.java:25)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:188)
... 21 more
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:304)
at
sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:992)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
... 29 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:154)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:297)
... 31 more
I don't understand what I am doing wrong because the file exists, the path is absolute, and is the same used by the server. Can someone please tell me what I am doing wrong?
I am using Java 8, mysql-connector-java-5.1.45
There are a few ways to do this. One put your self signed cert or the certificate authority you used to sign your cert into the default java key store used by the JVM you are using to connect with. You need to use the Keytool to do that. But unless your managing an enterprise VM package you probably dont want to hijack the default keystore in the security package.
First you need to understand how the key tool works.
[Java Key tool commands][1]https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
The problem is you may not have access to the default key store and it may not accept the certificate format your using. Requiring some gym work converting certificates and trying to match supported crypto algos.
Generally unless your managing an enterprise its better to just
generate a new keystore file
import your cert into this keystore ( or the certificate chain )
make sure you mark it as trusted
pass the keystore to your program at run time using the -D option.
I usually just add this to my code and set the properties before connecting to the DB
if (DB_SSL || SSL) {
System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASS);
System.setProperty("javax.net.ssl.trustStore", KEYSTORE);
System.setProperty("javax.net.ssl.trustStorePassword", KEYSTORE_PASS);
if (DEBUG_OPTION) {
System.setProperty("javax.net.debug", "true");
}
}
private static String KEYSTORE = "/home/me/.keystore";
private static String KEYSTORE_PASS = "changeit";

Java "Remote host closed connection during handshake" using Bittrex HTTP API

I've suddenly been getting these errors when making HTTP requests:
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:138)
... 24 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
... 41 more
It didn't always do this, it was working fine for awhile. I then used different libraries and even a different IntelliJ project for testing, still the same issues. Things I've tried:
Changing the endpoint I'm using
Setting the TLS version to TLSv1.2 (as I found when making a browser request)
I can load the endpoint fine with a browser and Postman. My code (using the Unirest library):
System.setProperty("https.protocols", "TLSv1.2");
System.out.println(Unirest.get("https://bittrex.com/api/v1.1/public/getmarketsummary?market=btc-ltc").asString().getBody());
I'm at a loss as to what could be causing this issue, and it's extremely frustrating. Any help would be appreciated.
EDIT: Updating to JDK10 fixed the issue. See the chosen answer and it's comment thread for more info.
First, turn on SSL debug: -Djavax.net.debug=all
Redirect your code's stdout to a file and check it for errors around handshaking.
If you examine the url you use with nmap or openssl:
nmap --script ssl-enum-ciphers -p <port> <host>
or
openssl s_client -connect <host>:<port>
(host: bittrex.com, port: 443)
you can see that is uses TLSv1.2 and ECDHE-ECDSA-AES128-GCM-SHA256 cypher:
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES128-GCM-SHA256
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-ECDSA-AES128-GCM-SHA256
Depending on your JDK version, you may need to install JCE extension and/or specify this cypher.
To be sure, you should print out the current supported cyphers using this little java code. If ECDHE-ECDSA-AES128-GCM-SHA256 not listed, this is your problem.

Import expired SSL certificate into Java keystore

I need to be able to point JMeter at a test server which has an expired SSL certificate (it will be some time before we are able to renew it). JMeter is quite rightly throwing an exception when it tries to connect:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:284)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:62)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1075)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1064)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:426)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:255)
at java.lang.Thread.run(Unknown Source)
Does anybody know of any way that I can import said certificate into the keystore and in the process change the expiry date (and would this even help or would the fact that the server certificate has expired still cause this exception to be thrown)?
I've tried to set the validity as part of the import but this is ignored:
keytool -import ... -validity 100
P.S - I know I could implement my own TrustManager which ignores these checks but my fingers won't allow me to write such evil code and I'd much rather get to a solution that I can install on the server without having to modify JMeter!
Thanks for your time.
JMeter does not validate certificate so this is not the cause of your issue.
Which implementation do you use, java, HC3 or HC4 ?
Your issue could come from error in Socket version negotation.
Try setting this in user.properties:
https.socket.protocols=SSLv2Hello SSLv3 TLSv1
You may have to play with them depending on your server configuration, for example only set this:
https.socket.protocols=SSLv3

secure imap connection in java

I am trying to connect to our imap server listening on port 993 using a java program I found at :
http://harikrishnan83.wordpress.com/2009/01/24/access-gmail-with-imap-using-java-mail-api/
I am running this program on from Ubuntu.
However, I am getting below exception for this :
DEBUG: setDebug: JavaMail version 1.4ea
DEBUG: getProvider() returning javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
javax.mail.MessagingException: Unrecognized SSL message, plaintext connection?;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:479)
at javax.mail.Service.connect(Service.java:275)
at javax.mail.Service.connect(Service.java:156)
at org.myorg.IMAP.main(IMAP.java:40)
Caused by: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
at com.sun.net.ssl.internal.ssl.InputRecord.handleUnknownRecord(InputRecord.java:523)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:355)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:753)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:97)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
at com.sun.mail.iap.ResponseInputStream.read0(ResponseInputStream.java:81)
at com.sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.java:67)
at com.sun.mail.iap.Response.<init>(Response.java:83)
at com.sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.java:48)
at com.sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.java:122)
at com.sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.java:230)
at com.sun.mail.iap.Protocol.<init>(Protocol.java:91)
at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:87)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:446)
... 3 more
At the end of this post they have suggested :
Looks like you have to add imap server’s certificate to your trusted cert store
Download imap server’s certificate
Locate your cacerts file
Use keytool to import the certificate to your cacerts file
However, I am not able to understand how to carry out these steps for an IMAP server running on Windows machine.
Could anybody pl. help me out here?
As the error message suggests, you are problably not connecting to a SSL encrypted port, but to a plaintext port. Please update your question with your actual configuration (host, port, protocol).
If you were missing the certificate, you would get a totally different error message.

Categories

Resources