使用Android OkHttpClient重用和缓存SSL连接
我使用改型和OkHttp来执行所有网络操作,比如HTTP和HTTPS url的GET、POST。一切正常,但我需要重用会话,以减少每次服务调用的握手计时过程。到目前为止,服务器为所有服务调用启动客户端和服务器之间的握手需要800毫秒以上的时间 我需要什么:使用Android OkHttpClient重用和缓存SSL连接,android,session,ssl,okhttp,retrofit2,Android,Session,Ssl,Okhttp,Retrofit2,我使用改型和OkHttp来执行所有网络操作,比如HTTP和HTTPS url的GET、POST。一切正常,但我需要重用会话,以减少每次服务调用的握手计时过程。到目前为止,服务器为所有服务调用启动客户端和服务器之间的握手需要800毫秒以上的时间 我需要什么: Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseURL) .a
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
.build();
retrofit.create(apiClass);
public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {
try {
if (inputStream != null) {
SSLContext sslContext = sslContextForTrustedCertificates(inputStream);
if (sslContext != null) {
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
else {
CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
private static SSLContext sslContextForTrustedCertificates(InputStream in) {
try {
CertificateFactory e = CertificateFactory.getInstance("X.509");
Collection certificates = e.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
} else {
char[] password = "password".toCharArray();
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
Iterator keyManagerFactory = certificates.iterator();
while (keyManagerFactory.hasNext()) {
Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
String sslContext = Integer.toString(index++);
keyStore.setCertificateEntry(sslContext, trustManagerFactory);
}
KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
var10.init(keyStore, password);
TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var11.init(keyStore);
SSLContext var12 = SSLContext.getInstance("TLS");
var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());
return var12;
}
} catch (Exception var9) {
var9.printStackTrace();
}
return null;
}
我必须重复使用SSLSession,以便使握手仅在第一次或特定的时间间隔内发生
我正在使用Okhttp和改型为SSL使用的代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
.build();
retrofit.create(apiClass);
public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {
try {
if (inputStream != null) {
SSLContext sslContext = sslContextForTrustedCertificates(inputStream);
if (sslContext != null) {
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
else {
CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
private static SSLContext sslContextForTrustedCertificates(InputStream in) {
try {
CertificateFactory e = CertificateFactory.getInstance("X.509");
Collection certificates = e.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
} else {
char[] password = "password".toCharArray();
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
Iterator keyManagerFactory = certificates.iterator();
while (keyManagerFactory.hasNext()) {
Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
String sslContext = Integer.toString(index++);
keyStore.setCertificateEntry(sslContext, trustManagerFactory);
}
KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
var10.init(keyStore, password);
TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var11.init(keyStore);
SSLContext var12 = SSLContext.getInstance("TLS");
var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());
return var12;
}
} catch (Exception var9) {
var9.printStackTrace();
}
return null;
}
我尝试过的:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient(context, new OkHttpClient(), context.getResources().openRawResource(R.raw.mysslcertificate)))
.build();
retrofit.create(apiClass);
public static OkHttpClient getOkHttpClient(Context context,OkHttpClient client, InputStream inputStream) {
try {
if (inputStream != null) {
SSLContext sslContext = sslContextForTrustedCertificates(inputStream);
if (sslContext != null) {
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
else {
CLog.i(Constants.LOG_TAG_HTTPLIBRARY,"GZip not done because it is not a Analytics data");
client = client.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory()).build();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
private static SSLContext sslContextForTrustedCertificates(InputStream in) {
try {
CertificateFactory e = CertificateFactory.getInstance("X.509");
Collection certificates = e.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
} else {
char[] password = "password".toCharArray();
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
Iterator keyManagerFactory = certificates.iterator();
while (keyManagerFactory.hasNext()) {
Certificate trustManagerFactory = (Certificate) keyManagerFactory.next();
String sslContext = Integer.toString(index++);
keyStore.setCertificateEntry(sslContext, trustManagerFactory);
}
KeyManagerFactory var10 = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
var10.init(keyStore, password);
TrustManagerFactory var11 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var11.init(keyStore);
SSLContext var12 = SSLContext.getInstance("TLS");
var12.init(var10.getKeyManagers(), var11.getTrustManagers(), new SecureRandom());
return var12;
}
} catch (Exception var9) {
var9.printStackTrace();
}
return null;
}
因为我找不到与OkHttpClient相关的任何内容,但我尝试引用了一些解决方案,如以下链接:
但坦率地说,没有什么对我有帮助,我甚至找不到任何相关的解决方案来满足我的需求。最后,我完全被这个解决方案困扰了两周。请通过您的任何提示和建议帮助我完成任务。任何一段代码或方法对我都非常有用。提前感谢。OkHttp支持SPDY和HTTP/2,它们为SSL提供了持续支持。您的服务器应配置为支持其中一种,在这种情况下,您的SSL会话重用将自动发生。@commonware感谢您的回复。对于SPDY和HTTP/2支持,我是否需要从服务器端实现任何东西?。如果我的服务器不支持SPDY和HTTP/2,请帮助我重新使用会话。这对我很有帮助。谢谢。“我是否需要从服务器端实现任何东西”——这是服务器配置的问题。请尝试解决这些问题。“如果我的服务器不支持SPDY和HTTP/2,如果您能帮助我重新使用会话,那将非常有帮助。”——我非常怀疑这是否可能。@Chandru即使没有SPDY或HTTP/2,您也可以缓存SSL会话,但这与OkHTTP/Android没有什么关系。您必须在服务器中配置它(如果它支持),或者找到另一个支持ssl会话缓存的web服务器。请确保它正在使用。如果是这样的话,那么在安卓方面确实会有问题