TLS-Verbindung mit SSLSocket langsam in Android-OS
Ich bin die Entwicklung einer Android-app, die verwendet SSLSocket eine Verbindung zu einem server. Dies ist der code den ich verwende:
//Connect
if (socket == null || socket.isClosed() || !socket.isConnected()) {
if (socket != null && !socket.isClosed())
socket.close();
Log.i(getClass().toString(), "Connecting...");
if (sslContext == null) {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
}
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
socket = (SSLSocket)socketFactory.createSocket(host, port);
socket.setSoTimeout(20000);
socket.setUseClientMode(true);
connected = true;
Log.i(getClass().toString(), "Connected.");
}
//Secure
if (connected) {
Log.i(getClass().toString(), "Securing...");
SSLSession session = socket.getSession();
secured = session.isValid();
if (secured) {
Log.i(getClass().toString(), "Secured.");
}
else
Log.i(getClass().toString(), "Securing failed.");
}
Das problem ist, dass es dauert etwa 5 Sekunden oder Ereignis mehr zu tun, der TLS-handshake in der Zeile darunter:
SSLSession session = socket.getSession();
Ich habe eine ähnliche iPhone-app, der Handschlag dauert nur 1 Sekunde da, so dass ich denke, das problem ist nicht der server bin ich verbunden, es ist vielleicht in dem code oben. Die Verbindung selbst ist schnell genug, nur der TLS-handshake ist langsam.
Weiß jemand, ob es normal bei Android, oder wenn es ist nicht, wie es schneller zu machen?
Danke.
BEARBEITET am 21.01.11:
Habe ich heraus gefunden, dass der handshake ist schnell, wenn ich eine Verbindung zu einem anderen server, zum Beispiel paypal.com:443.
Aber ich hatte die Verbindung zu einem anderen server bevor - ein .NET-service von mir geschrieben. Da hatte ich vorher sagte, ich glaube nicht, das problem war, dass die server, weil wenn ich eine Verbindung mit meinem iPhone App der handshake ist schnell. Nun weiß ich nicht, warum es ist schnell auf dem iPhone und langsam auf Android. Nachdem die Verbindung hergestellt wurde, die einzige Sache, die ich tun .NET-server ist:
Console.WriteLine("New client connected.");
this.sslStream = new SslStream(tcpClient.GetStream(), true);
this.sslStream.ReadTimeout = 15000;
this.sslStream.WriteTimeout = 15000;
Console.WriteLine("Beginning TLS handshake...");
this.sslStream.AuthenticateAsServer(connection.ServerCertificate, false, SslProtocols.Tls, false);
Console.WriteLine("TLS handshake completed.");
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es wurde ein bug in früheren Versionen des Android-SDK. Anscheinend ist dabei eine unnötige DNS-reverse-lookup. Sie müssen verhindern, dass dies geschieht. Hier ist ein workaround, der für mich gearbeitet. Es dauerte 15 Sekunden, jetzt dauert es 0-1 Sekunden. Hoffe, es hilft.
Hier ist der link zu Google Problem.
hostName
eine Ebene tiefer innerhalb einesInetAddressHolder
wrapper-Klasse (auch nicht, musste mehr Reflexion zu Durchlaufen, die). Trotzdem - vielen Dank.Sind Sie mit einem neuen
SecureRandom
pro Verbindung, anstelle der Verwendung einer einzelnen statischen pre-initializedSecureRandom
. Jedesmal, wenn Sie create a new SecureRandom(), die Sie benötigen, zu sammeln Entropie für das seeding (ein langsamer Prozess).SecureRandom nicht selbst Saatgut bis es zum ersten mal eingesetzt, weshalb die Verzögerung nicht auftreten, bis der Aufruf
getSession()
Habe ich etwas getan, was ähnlich wie diese, und es ist langsamer als eine ungesicherte Verbindung. Zugegeben mein Fall war https vs http-und es ist ein wenig anders, die SSL/TLS-Faktor hinzufügen Langsamkeit auf das Angebot ein.
Ich habe zwei identische apps, die komunizieren mit dem gleichen Protokoll auf dem gleichen server, eine in android-und ein iPhone, beide unter Verwendung von https. Wenn getestet habe ich Sie sowohl bei http, ich würde sehen, mehr oder weniger die gleiche Antwort Zeit, in https iOS war etwas schneller, in meinem Fall, aber nicht schrecklich.
Das problem ist wahrscheinlich in der Weise, die das Gerät überprüft die server-Zertifikate. Die Validierung einbeziehen können, um Kontaktaufnahme mit Dritten für Zertifikatsperrlisten und OCSP-Antworten. Wenn dies geschieht, braucht es Zeit. iPhone wahrscheinlich einfach nicht tun, diese (zumindest standardmäßig) das ist eine Sicherheitslücke, BTW.