这是接受自签名证书的有效方法吗?

时间:2011-10-12 12:17:39

标签: java certificate

我编写此代码以接受来自服务器的所有自签名证书:

private TrustManager[] createTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                if (!chain[0].getIssuerDN().equals(chain[0].getSubjectDN())) {
                    throw new CertificateException("This is not a self-signed certificate");
                }
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // leave blank to trust every client
            }
        }};
        return trustAllCerts;
    }

这是一种有效且充分的方法吗?

1 个答案:

答案 0 :(得分:3)

虽然它可以完成它的工作,但是你的方法基本上否定了正确的PKI的目的。如果您盲目地信任任何自签名证书,那么根本就没有必要使用TLS - 任何人都可以创建一个可以通过TrustManager的自签名证书。

因此,如果您想要安全,那么您应首先找出您的客户端应用程序将与哪些服务器进行通信,然后获取与这些服务相关联的TLS服务器证书(在您的服务中)方案中的每一个都是自签名的,因此您不需要关心中间证书。

现在,使用这些证书,您可以创建一个JKS“信任存储”文件并将证书放入其中 - 这是您要信任的证书集,此文件中未包含的证书将被拒绝。要创建JKS文件,您可以使用Java的keytool命令,也可以使用KeyStore API以编程方式执行此操作。

最后,您要创建SSLContext以供HttpClientinit使用,TrustManager创建如下:

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, pwd);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);

其中fin是您的“信任商店”的InputStreampwd是您用来加密它的密码。默认的TrustManager实现使您只需要一组可信证书即可使用,其余的将由您负责。