Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android-除了普通SSL证书之外,还验证自签名证书_Java_Android_Web Services_Ssl_Ssl Certificate - Fatal编程技术网

Java Android-除了普通SSL证书之外,还验证自签名证书

Java Android-除了普通SSL证书之外,还验证自签名证书,java,android,web-services,ssl,ssl-certificate,Java,Android,Web Services,Ssl,Ssl Certificate,我有一个通过SSL调用web服务的Android应用程序。在生产中,我们将拥有由可信CA签名的普通SSL证书。但是,我们需要能够支持自签名证书(由我们自己的CA签名) 我已经成功地实现了接受自签名证书的建议解决方案,但是由于中间人攻击的风险,这将不起作用。然后,我创建了一个trustmanager来验证证书链实际上是由我们的CA签署的 问题是我必须绕过正常的SSL验证——应用程序现在只会与安装了一个自签名证书的服务器通信 我有点迷路了,我在谷歌上搜索了很多地方,但什么也找不到。我希望找到一种方法

我有一个通过SSL调用web服务的Android应用程序。在生产中,我们将拥有由可信CA签名的普通SSL证书。但是,我们需要能够支持自签名证书(由我们自己的CA签名)

我已经成功地实现了接受自签名证书的建议解决方案,但是由于中间人攻击的风险,这将不起作用。然后,我创建了一个trustmanager来验证证书链实际上是由我们的CA签署的

问题是我必须绕过正常的SSL验证——应用程序现在只会与安装了一个自签名证书的服务器通信

我有点迷路了,我在谷歌上搜索了很多地方,但什么也找不到。我希望找到一种方法,通过编程将CA添加到设备上的信任存储中,因为这是处理该问题的最不具侵入性的方法

我想要达到的目标: 1.对普通SSL证书的完全标准支持。 2.对由我们自己的CA签名的自签名证书的额外支持


有什么建议吗?

你还没有发布任何代码,所以我不能确定你到底做了什么。但是,我假设您只使用自定义的
X509TrustManager
子类设置
SSLContext
。这很好,但您可以做的是让自定义的信任管理器实现也链接到内置的信任管理器。您可以在设置信任管理器时执行此操作;像这样的方法应该会奏效:

private List<X509TrustManager> trustManagers = new ArrayList<X509TrustManager>();

public MyCustomTrustManager() {
    TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmFactory.init((KeyStore)null);

    for (TrustManager tm : tmFactory.getTrustManagers()) {
        if (tm instanceof X509TrustManager)
            trustManagers.add((X509TrustManager)tm);
    }
}

parseDN()
的实现由您决定
subjectDN.getName()
将返回一个以逗号分隔的键值对列表(由
=
分隔),类似于
C=US,ST=California,L=Mountain View,O=Google Inc,CN=www.Google.com
。您需要CN(“公用名”)值用于主机名比较。请注意,如果您有通配符证书,它将以类似
*.example.com
的形式列出,因此在这种情况下,您需要做的不仅仅是简单的等号匹配。

您可以查看,也许会对您有所帮助。@ziziana这没有用。该页面上的示例允许任何证书,无论是有效的、无效的、撤销的、过期的、自签名的,等等。kelnos,谢谢。我没有发布代码,因为这个问题与接受自签名证书等无关。你的建议很好,但它没有解决其他需要检查的问题(如主机名验证等)。@Will777你在问题中没有问任何关于主机名验证的问题,“但我会更新我的答案以反映这一点。”凯尔诺斯说。然而,这就是我所说的“对普通SSL证书的完全标准支持”——标准验证包括主机名验证。谢谢你的帮助
Principal subjectDN = chain[0].getSubjectDN();
String subjectCN = parseDN(subjectDN.getName(), "CN");
if (this.allowedCN.equals(subjectCN)) {
    // certificate is good
}