2014-01-23 159 views
0

我試圖在PHP客戶端和Java服務器之間建立SSL連接。我對SSL一無所知,我對此很困惑。PHP客戶端和Java服務器之間的SSL套接字連接

連接不需要被信任或驗證,它只需要加密數據以使其安全傳輸。

PHP客戶端能夠連接(確認連接)和Java服務器,但在兩者之間的握手,我reveive在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 

和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 

這是我在Java代碼中負責處理插槽設置:

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); 
} 

這是處理連接到Java服務器我的PHP代碼: (在48行開始)

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

有人能幫忙解釋一下我做錯了或提供解決方案?

- 編輯

我已經使用Java客戶端連接到看到問題所在試過。但我仍然收到相同的錯誤,這是顯示在Java客戶端上:

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) 
+1

你有密鑰庫中的私鑰的合適證書嗎? 「*沒有共同的密碼套件* ...」[往往是由錯誤配置的密鑰庫導致](http://stackoverflow.com/a/15406581/372643)。你至少可以連接瀏覽器嗎?另外,在Java方面擁有這種信任管理器毫無意義(使用這些方法通常是一個糟糕的主意)。 (我不確定在PHP方面證書驗證是否足夠,使用'ssl://',但這可能很難修復。) – Bruno

+0

我使用命令'keytool -genkey -alias MyKey -keyalg RSA -keystore keystore .jks -keysize 2048'來生成我的密鑰庫。我已經修改了Java服務器現在不使用信任庫,但使用PHP客戶端時仍然發生相同的錯誤。我從我的密鑰庫中導出了公鑰,並將其作爲受信任的根CA安裝在Windows中,並嘗試使用簡單的Java客戶端進行連接,但同樣發生了同樣的錯誤。 –

回答

0

我發現問題是加載密鑰庫。我將它作爲資源檢索的方式不起作用。

我得到了正確加載的keystore,然後一切正常。

相關問題