Ich arbeite derzeit an einem Client-Server-Projekt.
Ich habe beschlossen, dass ich aus Sicherheitsgründen SSL verwenden sollte.Problem mit Java SSLSocket
Ich habe versucht, alle Socket
und ServerSocket
Objekte in ihre SSL-Varianten zu konvertieren, aber ohne Erfolg.
Wenn ich die SSLServerSocket
verwenden und eine Verbindung herstellen, friert der Socket-Ausgang auf der Server-Seite in der Mitte outputstream.write(byte[])
ein.
Hier sind die Funktionen, die ich verwenden, um die SSL-Sockets zu erstellen, ContextController.CONTEXT
die SSLContext
und Constants.DEBUG
ist eine schnelle Möglichkeit für mich, SSL zu wechseln:
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();
}
Wenn Constants.DEBUG = true
(dh SSL ausgeschaltet ist) es funktioniert , aber wenn SSL aktiviert ist, friert es wie oben beschrieben ein, nachdem einige Daten unbestimmt gesendet wurden. Wie kann ich das beheben?
EDIT:
ist die Quelle von ContextController.CONTEXT
:
(beachten Sie, ich weiß, ich eine tatsächliche TrustManager
verwenden sollte, aber zunächst möchte ich dies funktioniert)
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);
}
EDIT 2:
Hier ist ein StackTrace von wo es einfriert, beachten Sie, dass es nicht abstürzt, es hängt:
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
Ich habe einen Breakpoint die Zeile nach SocketStream.streamPacket(Packet) 181
platziert und es erreicht es nie.
Können wir sehen, wie ContextController.CONTEXT aussieht? – eli
Verwenden Sie 'SSLContext.getInstance (" TLS ");' anstelle von '" SSL "'. Implementieren Sie auch den TrustManager, wie Sie einen Server definieren. Da Sie keine Fehler gemeldet haben, ist es schwer zu sagen, was tatsächlich passiert. – eli
Das ist das Problem, es gibt keinen Fehler. Es friert einfach ein. –