Connexion TLS utilisant SSLSocket est lent dans le système d'exploitation Android
Je voudrais développer une application Android qui utilise SSLSocket pour se connecter à un serveur. C'est le code que j'utilise:
//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.");
}
Le problème est que cela prend environ 5 secondes ou plus pour faire la poignée de main TLS dans la ligne ci-dessous:
SSLSession session = socket.getSession();
J'ai fait une telle application iPhone, le temps est à seulement 1 seconde, donc je pense que le problème n'est pas dans le serveur, je suis connecté, c'est peut-être dans le code ci-dessus. La connexion en elle-même est assez rapide, juste la poignée de main TLS est lente.
Quelqu'un sait si c'est normal dans Android, ou si elle ne l'est pas, comment le rendre plus rapide?
Merci.
ÉDITÉ sur 21.01.11:
J'ai découvert, que la poignée de main est rapide lorsque je me connecte sur un autre serveur, par exemple paypal.com:443.
Mais j'avais été connecter à un autre serveur avant - un .NET service écrit par moi. Comme je l'avais dit avant, je ne pense pas que le problème était dans le serveur parce que si je m'y connecter avec mon iPhone App la poignée de main est rapide. Maintenant, je ne sais pas pourquoi il est rapide sur iPhone et lent sur Android. Une fois la connexion établie, la seule chose que je fais le .NET serveur est:
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.");
OriginalL'auteur Arthur | 2011-01-19
Vous devez vous connecter pour publier un commentaire.
Il y avait un bug sur les versions antérieures du SDK Android. Apparemment, il est inutile de faire un reverse DNS lookup. Vous devez empêcher que cela se produise. Voici une solution qui a fonctionné pour moi. Il sert à prendre 15 secondes, il prend maintenant 0-1 secondes. Espérons que cela aide.
Voici le lien vers le Google question.
hostName
un niveau plus profond à l'intérieur d'unInetAddressHolder
classe wrapper (également inaccessibles, besoin de plus de réflexion à traverser). Encore merci à vous.Merci Yuyo. le problème a me préoccupait depuis longtemps.
Fait mon backend demandes beaucoup plus rapide dans Android 6, semble que le bug malheureusement, il existe toujours dans le kit SDK d'Android.
OriginalL'auteur Yuyo
Vous utilisez un nouveau
SecureRandom
par connexion, au lieu d'utiliser un seul statique pré-initialiséSecureRandom
. Chaque fois que vous créez un nouveau SecureRandom(), vous devez rassembler entropie pour l'ensemencement (un processus lent).SecureRandom ne pas s'auto-amorçage jusqu'à ce qu'il est d'abord utilisé, c'est pourquoi le retard ne se produit pas jusqu'à ce que l'appel à
getSession()
Si c'était moi, je voudrais essayer d'obtenir une capture de paquets et de regarder où le ralentir. Est-il 1 seconde entre chaque paquet? Est-il un retard de temps entre les paquets (n) et (n+1), mais tout le reste rapide? Des choses comme cela.
Bonne idée, je vais essayer. J'ai découvert, que la poignée de main est vite quand je connet à un autre serveur, par exemple paypal.com:443. J'ai édité mon post, je pense que je dois changer quelque chose dans la .NET serveur mais je ne sais pas quoi, peut-être que le problème est dans le certificat du serveur, aucune idée..
Merci effectivement de réduire nos temps de la demande par la moitié, mais je suppose que ce serait pas si mal la régénération de la Sécuriser Hasard après un temps aléatoire!
OriginalL'auteur Jumbogram
J'ai fait quelque chose de semblable à cela, et il est plus lent que d'une connexion non sécurisée. Certes mon cas a été https vs http et c'est un peu différent de la SSL/TLS facteur va ajouter de la lenteur de l'affaire.
J'ai deux identiques applications communiquer avec le même protocole pour le même serveur, un android et un iPhone, à la fois en utilisant le protocole https. Quand j'ai testé les deux en http, je voudrais voir plus ou moins les mêmes temps de réponse, en https iOS a été légèrement plus rapide dans mon cas, mais pas terriblement.
OriginalL'auteur blindstuff
Le problème est probablement dans la façon dont l'appareil valide les certificats de serveur. La Validation peut vous demander de communiquer avec des tiers pour la Lcr et des réponses OCSP. Si cela se produit, il faut du temps. iPhone probablement juste de ne pas le faire (au moins par défaut) qui est un trou de sécurité BTW.
OriginalL'auteur Eugene Mayevski 'Allied Bits