简体   繁体   English

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

[英]Is this a valid approach to accept self-signed certificates?

I wrote this code to accept all self-signed certificates from a server: 我编写了以下代码,以接受来自服务器的所有自签名证书:

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;
    }

Is this a valid and sufficient approach? 这是有效且充分的方法吗?

Although it does its job, your approach basically denies the purpose of a proper PKI. 尽管可以做到,但是您的方法基本上否认了适当的PKI的目的。 If you blindly trust any self-signed certificate, then there is no point in using TLS at all - anyone can create a self-signed certificate that would pass your TrustManager . 如果您盲目地信任任何自签名证书,那么根本就没有使用TLS的任何人都可以创建将通过TrustManager的自签名证书。

So, if you want to be secure , then you should first find out which servers your client application will be communicating with and then get the TLS server certificates that are linked to those services (in your scenario each of them is self-signed, so you don't need to care about intermediate certificates). 因此,如果您想确保安全 ,则应该首先找出客户端应用程序将与之通信的服务器,然后获取链接到这些服务的TLS服务器证书(在您的方案中,每个服务器都是自签名的,因此您不需要关心中间证书)。

Now, using these certificates, you create a JKS "trust store" file and put the certificates in it - this is the set of certificates you are going to trust, certificates not contained in this file will be rejected. 现在,使用这些证书,您将创建一个JKS“信任存储”文件并将其放入其中-这是您要信任的一组证书,该文件中未包含的证书将被拒绝。 To create a JKS file you can either use Java's keytool command or you can do it programmatically using the KeyStore API. 要创建JKS文件,可以使用Java的keytool命令,也可以使用KeyStore API以编程方式进行操作。

Finally you would create the SSLContext to be used by your HttpClient and init it with a TrustManager created like this: 最后,您将创建供HttpClient使用的SSLContext ,并使用如下创建的TrustManager对其进行init

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

where fin is the InputStream of your "trust store" and pwd the password you used to encrypt it. 其中finInputStream你的“信任存储”和pwd您用于加密的密码。 The default TrustManager implementation this gives you needs only the set of trusted certificates to work with, the rest is taken care of for you. 默认的TrustManager实现使您只需要使用一组受信任的证书,其余的工作TrustManager您来处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM