2017-07-06 38 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结合在一起我按照我的要求加密了流量。

谢谢大家的帮助!