1

I'm attempting to setup an SSL connection between a PHP client and a Java server. I don't know a whole lot about SSL and I'm getting very confused with this.

The connection doesn't need to be trusted or verified, it just has to encrypt the data to make it safe for transfer.

The PHP client is able to connect (acknowledges a connection) to the Java server, but upon the handshake between the two, I reveive the following error in Java:

javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at sun.security.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1458)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:92)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at com.test.ConnectionHandler.getRequest(ConnectionHandler.java:23)
    at com.test.Interaction.run(Interaction.java:35)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
    at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:892)
    at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:620)
    at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:167)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
    at java.io.BufferedWriter.flush(BufferedWriter.java:254)
    at java.io.PrintWriter.newLine(PrintWriter.java:482)
    at java.io.PrintWriter.println(PrintWriter.java:629)
    at java.io.PrintWriter.println(PrintWriter.java:740)
    at com.test.ConnectionHandler.println(ConnectionHandler.java:28)
    at com.test.Interaction.run(Interaction.java:29)
    ... 1 more

and these errors in PHP:

Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:14077410:SSL routines:func(119):reason(1040) in /var/www/html/inc/node.class.php on line 48

Warning: fsockopen(): Failed to enable crypto in /var/www/html/inc/node.class.php on line 48

Warning: fsockopen(): unable to connect to ssl://127.0.0.1:30627 (Unknown error) in /var/www/html/inc/node.class.php on line 48

This is my code in Java which handles the socket setup:

SSLServerSocketFactory socketfactory;
SSLServerSocket ssock;

SSLContext sslContext = SSLContext.getInstance( "SSL" );

KeyStore ks = KeyStore.getInstance("JKS");
InputStream ksIs = ClassLoader.class.getResourceAsStream("resources/keystore.jks");
try {
    ks.load(ksIs, "password".toCharArray());
} catch (CertificateException e) {
    e.printStackTrace();
} finally {
    if (ksIs != null) {
        ksIs.close();
    }
}

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "password".toCharArray());

sslContext.init( kmf.getKeyManagers(), null, null );
socketfactory = sslContext.getServerSocketFactory();

socketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();

ssock = (SSLServerSocket) socketfactory.createServerSocket(myPort);

for(String item : ssock.getEnabledCipherSuites()) {
    System.out.println(item);
}

while(true) {
    SSLSocket sock = (SSLSocket) ssock.accept();

    new Interaction(sock);
}

This is my PHP code which handles the connection to the Java server: (Starting at line 48)

$this->stream = fsockopen("ssl://127.0.0.1", 30627, $errno, $errstr);
if(!$this->stream) {
  return array(
    'errornum' => $errno,
    'errorstr' => $errstr,
  );
} else {
  return true;
}

Can someone help explain what I'm doing wrong or provide a solution?

--Edit

I've tried using a Java client to connect to see where the problem lies. But I still receive the same error and this is shown on the Java Client:

javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHands
hakeException: Received fatal alert: handshake_failure
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.jav
a:1293)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.j
ava:1305)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.ja
va:43)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
        at java.io.BufferedWriter.flush(BufferedWriter.java:236)
        at Main.main(Main.java:55)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_
failure
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.ja
va:1720)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.j
ava:954)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
LSocketImpl.java:1138)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketIm
pl.java:753)
        at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:
75)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
        at java.io.InputStreamReader.read(InputStreamReader.java:167)
        at java.io.BufferedReader.fill(BufferedReader.java:136)
        at java.io.BufferedReader.readLine(BufferedReader.java:299)
        at java.io.BufferedReader.readLine(BufferedReader.java:362)
        at Main$Output.run(Main.java:77)
        at java.lang.Thread.run(Thread.java:662)
Jack B
  • 547
  • 4
  • 22
  • 1
    Do you have a suitable certificate with its private key in your keystore? "*No cipher suite in common*..." [tends to be caused by a misconfigured keystore](http://stackoverflow.com/a/15406581/372643). Can you at least connect with a browser? In addition, there's no point having that trust manager on the Java side (it's generally a bad idea to use those). (I'm not sure certificate validation is adequate on the PHP side, using `ssl://`, but that might be harder to fix.) – Bruno Jan 24 '14 at 09:51
  • I used the command `keytool -genkey -alias MyKey -keyalg RSA -keystore keystore.jks -keysize 2048` to generate my keystore. I've amended the Java server to not use the truststore now, but the same error is still occurring when using the PHP client. I exported the public key from my keystore and installed it in Windows as a trusted root CA, and tried to use a simple Java client to connect but, again, the same error occurs. – Jack B Jan 24 '14 at 17:48

1 Answers1

0

I figured out that the problem was with loading the keystore. The way I was retrieving it as a resource wasn't working.

I got the keystore to load correctly and everything then worked fine.

Jack B
  • 547
  • 4
  • 22