|
Forums -> Security Library Forum
"No Cipher Suites in Common" - C# Sockets talking to Java Sockets |
|
|
by James Jones [jbjones at chapman dot edu] posted on 2004/10/07 |
|
I am writing a generic C# SecureSocketClient class to talk to a Java SecureSocketServer. The java server is throwing the following exception: "SSLHandshakeException: no cipher suites in common". Is there a cipher suite from the list of those available that will work for both? The C# client eventually throws an exception: "A non-blocking socket operation could not be completed immediately" only because the server never sends back the data due to the exception.
Here are the suites I have found to be available:
(C#)
SslAlgorithms.ALL |
SslAlgorithms.RSA_3DES_168_SHA |
SslAlgorithms.RSA_AES_128_SHA |
SslAlgorithms.RSA_AES_256_SHA |
SslAlgorithms.RSA_DES_40_SHA |
SslAlgorithms.RSA_DES_56_SHA |
SslAlgorithms.RSA_RC2_40_MD5 |
SslAlgorithms.RSA_RC4_128_MD5 |
SslAlgorithms.RSA_RC4_128_SHA |
SslAlgorithms.RSA_RC4_40_MD5 |
SslAlgorithms.SECURE_CIPHERS | SslAlgorithms.NULL_COMPRESSION
(Java)
"SSL_RSA_WITH_RC4_128_MD5",
"SSL_RSA_WITH_RC4_128_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
"SSL_RSA_WITH_NULL_MD5",
"SSL_RSA_WITH_NULL_SHA",
"SSL_DH_anon_WITH_RC4_128_MD5",
"TLS_DH_anon_WITH_AES_128_CBC_SHA",
"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
"SSL_DH_anon_WITH_DES_CBC_SHA",
"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"
My certificate is standard (public key RSA (1024), signature md5RSA). Is there any cipher suites that will work with these? Has anyone done this?
Thanks,
Jim |
by Angel Todorov [angel at atodorov dot com] posted on 2004/10/08 |
|
just use SslAlgorithms.ALL on C#'s side, and then , RSA with AES CBC on Java's side for example, and you won't experience any problems. I have found that some of the supported suites in java are not supported by Mentalis, that's why you should use SslAlgorithms.ALL if possible. On the java side you can set the suite to be used like that :
String [] enabledsuites = s.getEnabledCipherSuites();
String [] suites = {SSLALGORITHM};
s.setEnabledCipherSuites(suites);
where enabledsuites is the set of all suites JSSE can use, and where SSLALGORITHM is any of them which mentalis can use, for example TLS_RSA_WITH_AES_128_CBC_SHA.
I hope this will work for you. |
by James Jones [jbjones at chapman dot edu] posted on 2004/10/11 |
|
Thank you for your response. I tried implementing the suggestion posted, and I received the following error (in java):
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) at CUSocketServer.main(CUSocketServer.java:155)
Do I need a certain type of certificate to allow this combination of cipher suites to work? I've used makecert to generate my certificates. How would I go about obtaining a cert that would work? |
by Angel Todorov [angel at atodorov dot com] posted on 2004/10/11 |
|
KeyManagerFactory kmf;
KeyManager[] km;
KeyStore ks;
TrustManagerFactory tmf;
TrustManager[] tm;
SSLContext sslc;
//Create a keystore that will read the JKS (Java KeyStore)
// file format which was created by the keytool utility.
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PASSWORD.toCharArray());
kmf = KeyManagerFactory.getInstance(ALGORITHM);
kmf.init(ks, KEYSTORE_PASSWORD.toCharArray());
km = kmf.getKeyManagers();
tmf = TrustManagerFactory.getInstance(ALGORITHM);
tmf.init(ks);
tm = tmf.getTrustManagers();
sslc = SSLContext.getInstance("TLS");
sslc.init(km, tm, null);
ServerSocketFactory ssf = sslc.getServerSocketFactory();
ss = ssf.createServerSocket(port);
In this way you load a certificate , initiate a secure socket factory, and create a server sock out of it, as an example. You generate the cert, for instance, using java's keytool utility.
|
by James Jones [jbjones at chapman dot edu] posted on 2004/10/13 |
|
I have implemented exactly what you have shown, but the big problem is that it's reporting that there are no cipher suites in common. I found that the "No available certificate corresponds to the SSL cipher suites which are enabled" error was corrected by using "SSL_DH_anon_WITH_RC4_128_MD5" as a suite, however they still do not have any cipher suites in common.
Has anyone tried getting the handshake to work between java ssl and these classes? I have been generating several test certificates, all with the same result. The list of ciphers I am using are listed above...
Any ideas would be appreciated. |
by Angel Todorov [angel at atodorov dot com] posted on 2004/10/13 |
|
well i am using the code above and it works pretty fine with me , with both client and server side authentication via certificates, java SSL server socket, and .NET client SecureSocket on the other hand. I am generating the java certificate with keytool, and the .NET certificate is a standard .p12 file. I am using .NET 1.1, and JDK 1.4.2. (which has integrated JSSE in it).
I am loading this certificate like that:
cer =
Certificate.CreateFromPfxFile(@"C:\\ca.p12",
"password");
for instance, and then use it like that:
options = new SecurityOptions(SecureProtocol.Tls1);
options.AllowedAlgorithms = SslAlgorithms.ALL;
options.Entity = ConnectionEnd.Client;
options.VerificationType = CredentialVerification.Manual;
options.Flags = SecurityFlags.Default;
options.Certificate = cer;
you can also set the Credential Verification to None. |
by James Jones [jbjones at chapman dot edu] posted on 2004/10/13 |
|
I've started from scratch, creating a new certificate with the keytool as well as generating the corresponding .p12 cert, and taking your code exactly, pasting it into new projects, and running them against one another. I also have java 1.4.2 and .NET framework 1.1. Here's the majority of the relevant code:
(JAVA SERVER CODE)
String cert = "C:\\Documents and Settings\\jbjones\\.keystore";
String pass = "*****";
int port = 10116;
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(cert), pass.toCharArray());
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, pass.toCharArray());
km = kmf.getKeyManagers();
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
tm = tmf.getTrustManagers();
sslc = SSLContext.getInstance("TLS");
sslc.init(km, tm, null);
ServerSocketFactory ssf = sslc.getServerSocketFactory();
ServerSocket ss = ssf.createServerSocket(port);
Socket tester = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(tester.getInputStream()));
BufferedOutputStream outStream = new BufferedOutputStream(tester.getOutputStream());
PrintStream outPrint = new PrintStream(outStream);
String line;
//read input
line = in.readLine();
NOTE: The exception occurs when calling in.readLine(): "SSLHandshakeException: no cipher suites in common"
(C# CLIENT CODE)
IPHostEntry ipHostInfo = Dns.Resolve(ip);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Certificate ssl = LoadPfxFile("c:\\testcert.p12", "ch4pm4n");//LoadCerFile("c:\\testcert.cer");
SecurityOptions security;// = new SecurityOptions(SecureProtocol.Ssl3 | SecureProtocol.Tls1, ssl, ConnectionEnd.Client);
security = new SecurityOptions(SecureProtocol.Tls1);
security.AllowedAlgorithms = SslAlgorithms.ALL;
security.Entity = ConnectionEnd.Client;
security.VerificationType = CredentialVerification.None;
security.Flags = SecurityFlags.Default;
security.Certificate = ssl;
//Create a TCP/IP socket
SecureSocket client = new SecureSocket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp, security);
// Connect to the remote endpoint
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne(connectTimeout, true);
// Send data to the remote device
Send(client, request + "\n");
sendDone.WaitOne(sendTimeout, true);
The c# client successfully sends the message. The java server throws the "no ciphr suites in common".
Do you have a working example you can email me at "jbjones at chapman dot edu"?
Thanks for your help,
Jim |
|
|