Art*_*hur 10 java sockets ssl android
我正在开发一个使用SSLSocket连接到服务器的Android应用程序.这是我正在使用的代码:
// 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.");
}
Run Code Online (Sandbox Code Playgroud)
问题是在下面的行中进行TLS握手需要大约5秒或更多事件:
SSLSession session = socket.getSession();
Run Code Online (Sandbox Code Playgroud)
我做了一个类似的iPhone应用程序,握手只需1秒钟,所以我认为问题不在我正在连接的服务器中,它可能在上面的代码中.连接本身足够快,只是TLS握手很慢.
有人知道它在Android中是否正常,或者如果不是,如何让它更快?
谢谢.
于21.01.11编辑:
我发现,当我连接到另一台服务器时握手很快,例如paypal.com:443.
但我以前连接过另一台服务器 - 我写的一个.NET服务.正如我之前所说,我不认为问题出现在那台服务器上,因为如果我用我的iPhone App连接它,握手很快.现在我不知道为什么它在iPhone上速度快,在Android上速度慢.建立连接后,我在.NET服务器中做的唯一事情是:
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.");
Run Code Online (Sandbox Code Playgroud)
早期版本的Android SDK存在一个错误.显然,它正在进行不必要的DNS反向查找.你需要防止这种情况发生.这是一个对我有用的解决方法.过去需要15秒,现在需要0-1秒.希望能帮助到你.
这是Google 问题的链接.
boolean connected = false;
if (socket == null || socket.isClosed() || !socket.isConnected()) {
if (socket != null && !socket.isClosed()) {
socket.close();
}
Log.i(getClass().toString(), "Connecting...");
messages.getText().append("Connecting...");
final KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(getResources().openRawResource(R.raw.serverkey), null);
final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManager.init(keyStore, null);
//keyManager.init(null, null);
final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), rnd);
final SSLSocketFactory delegate = sslContext.getSocketFactory();
SocketFactory factory = new SSLSocketFactory() {
@Override
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
InetAddress addr = InetAddress.getByName(host);
injectHostname(addr, host);
return delegate.createSocket(addr, port);
}
@Override
public Socket createSocket(InetAddress host, int port)
throws IOException {
return delegate.createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException {
return delegate.createSocket(host, port, localHost, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return delegate.createSocket(address, port, localAddress, localPort);
}
private void injectHostname(InetAddress address, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(address, host);
} catch (Exception ignored) {
}
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
injectHostname(s.getInetAddress(), host);
return delegate.createSocket(s, host, port, autoClose);
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
};
socket = (SSLSocket)factory.createSocket("192.168.197.133", 9999);
socket.setSoTimeout(20000);
socket.setUseClientMode(true);
connected = true;
Log.i(getClass().toString(), "Connected.");
messages.getText().append("Connected.");
}
// Secure
if (connected) {
Log.i(getClass().toString(), "Securing...");
messages.getText().append("Securing...");
SSLSession session = socket.getSession();
boolean secured = session.isValid();
if (secured) {
Log.i(getClass().toString(), "Secured.");
messages.getText().append("Secured.");
}
}
Run Code Online (Sandbox Code Playgroud)
我已经做了类似的事情,它比不安全的连接慢。当然,我的情况是 https 与 http,但略有不同,SSL/TLS 因素会增加交易速度。
我有两个相同的应用程序,它们使用相同的协议与同一服务器进行通信,一个在 Android 中,一个在 iPhone 中,都使用 https。当我在 http 中测试它们时,我会看到或多或少相同的响应时间,在 https 中,iOS 在我的情况下稍微快一点,但不是特别快。
归档时间: |
|
查看次数: |
11861 次 |
最近记录: |