我目前正在開發一個客戶端服務器項目。
我決定我應該使用SSL出於安全原因。Java問題SSLSocket
我試圖將所有Socket
和ServerSocket
對象轉換爲SSL變體,但無濟於事。
當我使用SSLServerSocket
並連接到它時,服務器端的套接字輸出在outputstream.write(byte[])
中間凍結。
下面是功能我用它來創建SSL套接字, ContextController.CONTEXT
是SSLContext
和Constants.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
之後放置了一個斷點,它永遠不會到達它。
我們可以看到ContextController.CONTEXT是怎麼樣的嗎? – eli
使用'SSLContext.getInstance(「TLS」);'而不是'「SSL」'。另外,當你定義一個服務器時,實現'TrustManager'。由於您沒有提供任何錯誤,因此很難說出實際發生的情況。 – eli
這就是問題所在,沒有錯誤。它只是凍結。 –