Woozle Wuzzle
Don't forget to set the cipher suite!

I was attempting to use a vanilla SSL server and client socket (such as outlined in this article) but kept getting the dreaded:

javax.net.ssl.SSLException: No available certificate corresponds 
to the SSL cipher suites which are enabled.

The usual searches turned up a million posts about junk I already knew. The JSSE ref guide is great for people that already know what they're doing an is therefore self deprecating.

The long and short of it is that if you use a default SSLServerSocketFactory and create a socket then you must have an anonymous cipher suite installed. For example:

final SSLServerSocketFactory sslSocketFactory = 
    (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
final SSLServerSocket sslServerSocket = 
    (SSLServerSocket)sslSocketFactory.createServerSocket(port);

// use an anonymous cipher suite so that a KeyManager or TrustManager
// is not needed
// NOTE:  this assumes that the cipher suite is known.  A check -should-
//        be done first.
final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
sslServerSocket.setEnabledCipherSuites(enabledCipherSuites);

A unless you do the same on the client side, you will receive the following:

javax.net.ssl.SSLHandshakeException: no cipher suites in common
javax.net.ssl.SSLHandshakeException: 
    Received fatal alert: handshake_failure

Link-back to main entry: NIO and SSL.

Comments
Comment by Richard Pearce at October 3, 2004 06:32 PM

Thanks! .. I was trying all manner of things to make it work for 5 hours!! .. And you solved it .. Thanks ;)

 

Comment by rgrzywinski at October 4, 2004 08:40 AM

There is no better feeling than to wake up and find out that you have helped a fellow developer.

Thank you.

 

Comment by Daniel Wamara at October 21, 2004 09:07 AM

Hi Rod,

I also tried it but it's still not working. I've also tried to list all the supported cypher suites and enabled them but no luck and this thing is really supposed to be working for yesterday.

D.

 

Comment by rgrzywinski at October 21, 2004 09:20 AM

Well, let's start with defining "not working". What are the exceptions and can you pare down the code to just something that we can work with?

Email me directly if you want so that we can expidite this.

 

Comment by Daniel Wamara at October 25, 2004 01:50 AM

Don't worry, it did worked :-) I was just setting the cypher suites on the client side and I just forgot to do it on the server side when I wanted to give a message back.

It's all good now, I mean, on the test server, because on the customer side, I still got problem but with some socket closed problem, I think it has to see with the certificates and all. I hope to solve it by the end of the day, but your help was more than appreciated.

D.

 

Comment by Richard Pearce at October 25, 2004 04:12 AM

If you dont want to have to use an anonymous set of cipher suites you can use the following:

System.setProperty("javax.net.ssl.keyStore", System.getProperty("user.home") + File.separator + "keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "yourpassword");
SSLServerSocketFactory factory =(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
serverSocket = (SSLServerSocket) factory.createServerSocket(port); // Create the ServerSocket

Make sure you have a valid keystore (Server) and Truststore (Client)
If you want to create them follow these instructions and you cant go wrong: http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#CreateKeystore

-Rich

 

Comment by rgrzywinski at October 25, 2004 06:20 AM

Thanks for the tip Rich!

I feel obligated to point out though that I would not use that code in anything other than a proof of concept or a test. Java security 101 says that passwords should never be passed around as Strings (they should be char[]s) and even with a suitable SecurityManager, putting the keystore password in the environment (System.XXXProperties) is not a good idea.

 

Comment by jitendra at December 15, 2004 07:21 AM

javax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites which are enabled.
at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.a(DashoA6275)
at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.accept(DashoA6275)

 

Comment by rgrzywinski at December 15, 2004 10:40 AM

I'm assuming jitendra that that's a question. You're going to need to provide a bit more information such as what -are- the available cipher suites, what JDK (version and provider) and any other relevant factors (perhaps platform, other jars, etc).

 

Comment by Stephen Kuenzli at February 5, 2005 10:24 PM

Thanks for the helpful page. It got me going in the right direction. Sometimes, your client will settle for an anonymous cipher, but Sun's Java (1.4.1) does not enable those by default. To let clients use whatever your libraries support do something like:

SSLServerSocketFactory socket_fact = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket ssl_server_socket = (SSLServerSocket)SSLServerSocketFactory.getDefault().createServerSocket(port);
ssl_server_socket.setEnabledCipherSuites(ssl_server_socket.getSupportedCipherSuites());

Regards,
Stephen

 

Comment by Filipe Nunes at May 7, 2005 12:25 PM

Thanks!
I was having the same problem and your tip saved me a huge amount of time.

 

Comment by BlackYoda at June 3, 2005 04:01 PM

Thanks this was a very helpful page I found through google. I was doing a quick test to make sure that I could get a custom SSL client talking to a custom SSL server, and got it working quickly thanks to your page.

I was following the directions on this page for my quick-bang proof of concept:

http://javaalmanac.com/egs/javax.net.ssl/Server.html?l=rel

It does not mention setting the cypher suite there, but that fixed it. First I did the anonymous cyhpher as you suggested, and then I read in the comments about making all the available cyphers available, and that worked too.

I don't understand why it does not just do that automatically really! If I specify that all the ciphers are enabled, which one does it use? Does it really matter? Is the transaction still secure?

 

Comment by Peter at June 16, 2005 01:06 PM

How is it possible to enable the cipher if i want to acces my server via my browser (IE) ??

also, where do i enable them in my tomcat??

 

Comment by James Aguilar at July 25, 2005 09:16 AM

This entry saved my life. It seems like no one else wants anonymous SSL, but I needed it! Thanks!

 

Comment by Gerald Hanweck at September 21, 2005 10:19 AM

I ran into this problem when I imported my CA certificates into the wrong keystore, and tried a lot of suggestions from many other formus before coming across this solution:

*** Make sure you import the CA certificates into the same keystore you used to create the certificate request. ***

That ensures that you have a valid key entry in the keystore so keytool or whatever can build the proper certificate chain.

Thawte's website has a nice set of troubleshooting tips.
http://search.thawte.com/thawte/solutionDisplay.do;jsessionid=F9CD74D583D00F11B0804A367BB324BD?clusterName=DefaultCluster&groupId=1&docType=1006&docProp=$solution_id&docPropValue=vs7948&gotoLink=0&resultType=5002&directSolutionLink=1

 

Comment by Priolkar at December 7, 2005 08:45 AM

Hi All, I have configured tomcat for https. and have given heystore path inside the server.xml explicitly for verisign.keystore. but when i try to start the server i get

"SEVERE: Endpoint [SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=8080]] ignored exception: java.net.SocketException:
SSL handshake errorjavax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites which are enabled."

plz help

 

Comment by rgrzywinski at December 8, 2005 06:25 AM

Priolkar, it's difficult to help without knowing what you've already tried. I'm assuming that you've read all of the other comments associated with this entry including the one from Mr. Hanweck?

 

Comment by Chris Friess at December 12, 2005 06:40 AM

In what configuration file do you add these lines to prevent this dreaded error. Thanks, Chris

 

Comment by Praveen at January 30, 2006 08:55 AM

Thanks for the tips on JSSE, i tried to implement the same and solved quite a lot of problems, but now im encounterring something new

below is the code snippet in Server.java

SSLServerSocketFactory sslSrvFact = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
s =(SSLServerSocket)sslSrvFact.createServerSocket(PORT);
final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
s.setEnabledCipherSuites(enabledCipherSuites);


SSLSocket c = (SSLSocket)s.accept();


Code Snippet from Client.java is as follows

SSLSocketFactory sslFact =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)sslFact.createSocket(LOCALHOST, PORT);
final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
socket.setEnabledCipherSuites(enabledCipherSuites);

the exception i encounter on Client Side is

java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(Unknown Source)

at the same time i get the following exception on Server side

( Server.java:82) - java.net.BindException: Address already in use: JVM_Bind


host is specified as localhost
and port is specified as 8123

the abv program works with plain socket communication.

Please let me know the solution if you have any

thanks in advance

 

Comment by V. Jenks at May 24, 2006 11:12 AM

I'm trying to get ssl (https) working in JBoss (which is actually tomcat underneath) and I am obviously not "in the know" when it comes down to it. I've been able to setup SSL certs for Apache and IIS in minutes....I've been banging on Tomcat for a week now and it just doesn't make sense.

This article is the most descriptive, however, you don't mention how this would apply in my case?

I actually ran your code using port 8443 and it didn't fail...but I don't see how I could run this "server" while running JBoss at the same time, the ports would conflict.

What can I do?

 

Comment by rgrzywinski at May 25, 2006 06:19 AM

V. Jenks, this post was initially about a standalone SSL server (which I was writing as part of a security product). Unfortunately, it doesn't help you in any way and for that I apologize. I've heard of people having your exact problems but I don't know of anyone that has a quick and fast solution. Again, sorry. If you do ever come up with a solution please remember to post it someplace (here, perhaps) so that your knowledge can help everyone!

Good luck!

 

Comment by Scott Y at July 9, 2006 06:18 PM

Hello, I have the server working with alot of reading and trail/error approach. The issue that I'm having is getting curl to talk to the java ssl server. All the examples use a server.cer file and curl needs a server.pem. I have created a cert with CA.sh and imported it on the server side, but know I get the no cipher suites in common error. Help and thank you in advance. BTW, I get the same error from my browser.

 

Comment by Farhana Ashraf at June 26, 2007 04:57 PM

Found the tips really useful.

Thanks

 

Comment by Drakanor at October 6, 2007 12:47 PM

Thanks a lot for this thread, it saved my day. While perfectly working with Java on Windows, my application kept complaining about missing cipher suites on Linux. This line of code I found here did the job:

serverSocket.setEnabledCipherSuites(serverSocket.getSupportedCipherSuites());

Thanks,
Drakanor

 

Comment by rgrzywinski at October 7, 2007 07:40 AM

Glad I could be of some help.

Take care!

 

Comment by Powell at February 25, 2008 01:43 PM

Great post. I was messing around with ssl (new area for me) and couldn't figure out how to get it working. This helped a lot, thanks.

 

Comment by Bruno Harbulot at August 4, 2008 08:21 AM

It's a good idea to explain how to configure the cipher suites, but perhaps this entry should come with a word of warning. Anonymous cipher suites offer virtually no security against man-in-the-middle attacks, which are one of the main reasons to use SSL in the first place. An SSL connection that uses an anonymous cipher suite is virtually as good as not using SSL at all: these cipher suites should never be used in production.

Cheers.

 

Comment by moin at December 2, 2008 05:06 AM

thanks to provide this
you solve my big problem

 

Comment by PXC-FIB at May 9, 2010 10:39 AM

Thanks dude! After full weekend we resolved the problem with this post! Sounds stupid but true!

Best regards from Barcelona, Catalonia

 

Post a comment













Remember personal info?






Creative Commons License Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License.