- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我们的应用程序中,当应用程序与服务器通信时,我会额外检查证书(公钥固定)(针对 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(套接字、主机、端口、自动关闭);
为什么?因为 Hostname 验证不是通过 sslSocketFactory.createSocket(InetAddress, int) 方法执行的。
sslSocket = (SSLSocket) sslSocketFactory.createSocket(InetAddress.getByName(主机), 端口);
还有'isSecure'方法也写在了帖子里,因为我们不知道我们使用的是什么端口,所以如果socket的实例是ssl,检查它是否连接。如果是,则 isSecure 应返回 true,否则返回 false。
关于android - 自定义 SSLSocketFactory 不使用自定义 trustmanager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27886134/
我如何在 grails 中使用以下代码—— TrustManager[] trustAllCerts = new TrustManager[]{ new X509Tru
我正在尝试创建一个 TrustManagers 数组,其中填充了从 Base64 编码的 PEM 字符串解码的 CA 证书,以便在 SSLSocketFactory 中传递它。这是我的代码: publ
我正在围绕我们内部使用的一些其余 Web 服务构建一个小型包装器 Java 类。我们使用安全的 HTTPS 连接。通常,SSL 只允许受信任的证书。我希望包装类的用户能够将 X509Certifica
我正在努力使我的 Android 应用程序符合 Android 的新政策,即根据此 requirement and instructions 拥有安全应用程序. 1) 我首先将 SSL 和 https
我想将自定义信任管理器分配给特定的 org.apache.axis.client.Call。对于 Java 中的常规 HTTP 客户端,我只需创建一个 SSLContext 和 TrustManage
在什么情况下会在 Java 中使用 HostnameVerifier 而不是 TrustManager?一个比另一个推荐吗?查看 Java 文档(Interface HostnameVerifier
我试图找出 HTTPS 连接中使用的 TrustManager 和 keyManager 之间的区别。如果发布了相同的引用资料,那将会很有帮助,因为我无法获得正确的信息。 谢谢和问候,苏伦达尔 最佳答
在我们的应用程序中,当应用程序与服务器通信时,我会额外检查证书(公钥固定)(针对 MITMA)。为了与服务器通信,我使用 HttpClient。另外我在生产中有一些代理服务器,所以我需要使用 SNI。
在我的项目使用 1.4.0.M3 版本的 Spring Boot 前几周,它使用 tomcat-embedded-core-8.0.33。在这里,我能够使用以下代码创建多连接器: @Bean Embe
我有一个要求,可以提供一个中间 CA 来信任,但不能提供签署它的 CA。并将其用作信任库,我希望能够信任具有由该中间 CA 签名的证书的 SSL 服务器。默认实现是期望构建整个链,直到找到受信任的自签
我已经阅读了很多关于设置我的 SSL 客户端/服务器系统(无 HTTP)的资料。 我的灵感来自 the secure chat example和 the websocket ssl server ex
在开发者控制台中我的应用名称旁边看到了来自 Google 的警告,内容涉及 TrustManager 的不安全实现。我浏览了代码,但没有使用 TrustManager 或 checkServerTru
在 Mac 上的 Eclipse 4.3.2 Java 1.7 中调试某些代码时,我出现了非常奇怪的行为。 我有一些库(没有源代码),可能定义它自己的TrustManager(我的猜测)。当在调试期间
我正在尝试在 IBM 云 VM (Ubuntu 18) 上启动一个 spring 应用程序。我使用的命令是 java -jar application.jar。它使用 spring 数据和 SSL 证
我正在尝试使用以下代码绕过证书: private static HttpClient wrapClient(HttpClient base) 抛出 AGException { 尝试 { SSLCont
在我当前基于 netty (3.5.2) 的服务器中 I am able to ask the client for a certificate using TLS renegotiation .根据
对 keystore 和信任库使用 KeyStore 对象有什么区别?而不是使用 KeyManager 和 TrustManager? 让我解释一下我为什么要问。我正在使用 RESTEasy,需要使用
首先我不得不承认,我知道接受所有证书可以被认为是没有安全性的。我们有“真正的”证书,但只在我们的实时系统上。我们测试系统上的证书是自签名的。所以只要我们在开发,我们就必须使用测试服务器,这迫使我禁用证
我一直在尝试使用 apache HttpClient 库注册我的自定义 TrustManger。以下链接包含有关如何执行此操作的说明:Https Connection Android 不幸的是,我想使
我有一个与 HTTPS RPC 通信的应用程序。 HTTP 服务器正在使用 CAcert 签名证书。 我正在使用自定义 TrustManager 来验证证书。 因为我不能确定,CAcert 包含在所有
我是一名优秀的程序员,十分优秀!