2017-07-06 85 views
0

我目前正在開發一個客戶端服務器項目。
我決定我應該使用SSL出於安全原因。Java問題SSLSocket

我試圖將所有SocketServerSocket對象轉換爲SSL變體,但無濟於事。
當我使用SSLServerSocket並連接到它時,服務器端的套接字輸出在outputstream.write(byte[])中間凍結。

下面是功能我用它來創建SSL套接字, ContextController.CONTEXTSSLContextConstants.DEBUG是一個快速的方式對我來說,切換SSL:

public static ServerSocket server(int port, int backlog) throws IOException { 
    return Constants.DEBUG ? new ServerSocket(port, backlog) : CONTEXT.getServerSocketFactory().createServerSocket(port, backlog); 
} 

public static Socket client(InetSocketAddress address) throws IOException { 
    return Constants.DEBUG ? new Socket(address.getHostName(), address.getPort()) 
      : ContextController.CONTEXT.getSocketFactory().createSocket(address.getHostName(), address.getPort()); 
} 

public static Socket client() throws IOException { 
    return Constants.DEBUG ? new Socket() : ContextController.CONTEXT.getSocketFactory().createSocket(); 
} 

Constants.DEBUG = true(即SSL關閉)它的工作原理,但是當SSL打開時,會在無限期地發送一些數據後如上所述凍結。我怎樣才能解決這個問題?

編輯
這裏是ContextController.CONTEXT來源:
(注意,我知道我應該用實際TrustManager但首先我想這個工作)

if (server) {// load the keystore 
     try (FileInputStream fis = new FileInputStream(ks)) { 
      CONTEXT = SSLContext.getInstance("SSL"); 

      // load the keystore from the file 
      KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      keystore.load(fis, PASSWORD); 

      // setup the KeyManagerFactory (used by the server) 
      KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
      kmf.init(keystore, PASSWORD); 

      CONTEXT.init(kmf.getKeyManagers(), null, null); 
     } 
     catch (Exception e) { 
     } 
    } 
    else { 
     CONTEXT = SSLContext.getInstance("SSL"); 
     CONTEXT.init(null, new TrustManager[] { new X509TrustManager() { 
      @Override 
      public void checkClientTrusted(X509Certificate[] chain, String authType) { 
      } 

      @Override 
      public void checkServerTrusted(X509Certificate[] chain, String authType) { 
      } 

      @Override 
      public X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
     } }, null); 
    } 

編輯2
這裏是它凍結的堆棧軌跡,注意它不會崩潰,它會掛起:

Thread [ClientExecThread #0] (Suspended)  
owns: AppOutputStream (id=54) 
owns: ByteArrayOutputStream (id=55)  
SocketOutputStream.socketWrite0(FileDescriptor, byte[], int, int) line: not available [native method] 
SocketOutputStream.socketWrite(byte[], int, int) line: 111 
SocketOutputStream.write(byte[], int, int) line: 155  
OutputRecord.writeBuffer(OutputStream, byte[], int, int, int) line: 431 
OutputRecord.write(OutputStream, boolean, ByteArrayOutputStream) line: 417 
SSLSocketImpl.writeRecordInternal(OutputRecord, boolean) line: 876 
SSLSocketImpl.writeRecord(OutputRecord, boolean) line: 847 
AppOutputStream.write(byte[], int, int) line: 123 
ByteArrayOutputStream.writeTo(OutputStream) line: 167 
SocketStream.streamPacket(Packet) line: 181 
ClientThread.lambda$8(Group) line: 150 
1427646530.run(Object) line: not available 
ClientThread.execute() line: 444  
ClientThread$ClientExecThread.run() line: 261 

我在SocketStream.streamPacket(Packet) 181之後放置了一個斷點,它永遠不會到達它。

+0

我們可以看到ContextController.CONTEXT是怎麼樣的嗎? – eli

+0

使用'SSLContext.getInstance(「TLS」);'而不是'「SSL」'。另外,當你定義一個服務器時,實現'TrustManager'。由於您沒有提供任何錯誤,因此很難說出實際發生的情況。 – eli

+0

這就是問題所在,沒有錯誤。它只是凍結。 –

回答

-1

我真的不知道爲什麼發生這種情況,我不需要SSL的所有方面(只有加密部分,爲什麼我沒有實現TrustManager),所以我決定實施一個Diffie Hellman。

這可按預期工作,並將DH與AES結合在一起我按照我的要求加密了流量。

謝謝大家的幫助!