gpt4 book ai didi

android - 自定义 SSLSocketFactory 不使用自定义 trustmanager

转载 作者:行者123 更新时间:2023-11-29 20:55:35 33 4
gpt4 key购买 nike

在我们的应用程序中,当应用程序与服务器通信时,我会额外检查证书(公钥固定)(针对 MITMA)。为了与服务器通信,我使用 HttpClient。另外我在生产中有一些代理服务器,所以我需要使用 SNI。在我们将应用程序发布到生产环境之前,我们会在另一个环境 (TEST env) 中对其进行检查。对于 TEST env,我们只有自签名证书,因为它仅用于测试,我们不想仅为这种情况购买新证书。

为了实现它,我创建了自定义 SSLSocketFactory (org.apache.http.conn.ssl.SSLSocketFactory)。但问题是它不适用于自签名证书。我将自定义 trustManager (IgnoreCertificatesTrustManager) 设置为 sslSocketFactory (SSLCertificateSocketFactory)。如果我使用以下代码:

SSLContext sslContext = SSLContext.getInstance(SSLSocketFactory.TLS);
sslContext.init(null, new TrustManager[] { new IgnoreCertificatesTrustManager() }, null);
sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);

自签名证书的检查有效(忽略 TrustManager (IgnoreCertificatesTrustManager) 中的检查)。但是代码不支持 SNI 解决方案。我做错了什么?

谢谢。

private class CustomSSLSocketFactory extends SSLSocketFactory {

public CustomSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, CertificateException {
super(null);
}

// Plain TCP/IP (layer below TLS)

@Override
public Socket connectSocket(Socket s, String host, int port, InetAddress localAddress, int localPort, HttpParams params) throws IOException {
return null;
}

@Override
public Socket createSocket() throws IOException {
return null;
}

@Override
public boolean isSecure(Socket s) throws IllegalArgumentException {
if (s instanceof SSLSocket) {
return ((SSLSocket) s).isConnected();
}
return false;
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
SSLSocket sslSocket = null;

// if (isProduction()) {
if (autoClose) {
// we don't need the plainSocket
socket.close();
}

// create and connect SSL socket, but don't do hostname/certificate verification yet
SSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0, null);


// NOT works!
sslSocketFactory.setTrustManagers(new TrustManager[] { new IgnoreCertificatesTrustManager() });
// ----


sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, autoClose);

// enable TLSv1.1/1.2 if available (see https://github.com/rfc2822/davdroid/issues/229 )
sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());

// set up SNI before the handshake
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
logger.debug("Setting SNI hostname");
sslSocketFactory.setHostname(sslSocket, host);
} else {
logger.debug("No documented SNI support on Android <4.2, trying with reflection");
try {
java.lang.reflect.Method setHostnameMethod = sslSocket.getClass().getMethod("setHostname", String.class);
setHostnameMethod.invoke(sslSocket, host);
} catch (Exception e) {
logger.error("SNI not useable", e);
}
}

// } else {
// try {
// SSLContext sslContext = SSLContext.getInstance(SSLSocketFactory.TLS);
// sslContext.init(null, new TrustManager[] { new IgnoreCertificatesTrustManager() }, null);
// sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
// } catch (java.security.NoSuchAlgorithmException e) {
// throw new IOException(e);
// } catch (KeyManagementException e) {
// throw new IOException(e);
// }
// }

// verify certificate
SSLSession session = sslSocket.getSession();
X509Certificate[] certificates = (X509Certificate[]) session.getPeerCertificates();

if (!checkPublicKey(certificates)) {
throw new IOException("SSL_HANDSHAKE_FAILED");
}

return sslSocket;
}

}

最佳答案

我发现了问题。我的错。而不是线:
sslSocket = (SSLSocket) sslSocketFactory.createSocket(套接字、主机、端口、自动关闭);
你应该使用:
sslSocket = (SSLSocket) sslSocketFactory.createSocket(InetAddress.getByName(主机), 端口);
为什么?因为 Hostname 验证不是通过 sslSocketFactory.createSocket(InetAddress, int) 方法执行的。

还有'isSecure'方法也写在了帖子里,因为我们不知道我们使用的是什么端口,所以如果socket的实例是ssl,检查它是否连接。如果是,则 isSecure 应返回 true,否则返回 false。

关于android - 自定义 SSLSocketFactory 不使用自定义 trustmanager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27886134/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com