简体   繁体   中英

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. 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 .

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).

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. To create a JKS file you can either use Java's keytool command or you can do it programmatically using the KeyStore API.

Finally you would create the SSLContext to be used by your HttpClient and init it with a TrustManager created like this:

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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