Java and SSL certificates

前端 未结 6 1879
闹比i
闹比i 2020-12-03 05:23

I am trying to establish a connection with a PHP script of mine in Java using the secure socket layer (HTTPS), but I have found out that to ensure maximum security/validity

6条回答
  •  清歌不尽
    2020-12-03 06:27

    The following method loads the default (cacerts) keystore, checks to see if a certificate is installed, and installs it if not. It eliminates the need to manually run the keystore command on any servers.

    It assumes that the default keystore password (changeit) is unchanged, update CACERTS_PASSWORD if not. Note that the method saves the keystore after adding a certificate, so after being run once the certificate will permanently be in the store.

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    
    /**
     * Add a certificate to the cacerts keystore if it's not already included
     */
    public class SslUtil {
        private static final String CACERTS_PATH = "/lib/security/cacerts";
    
        // NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG
        // DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE
        // ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO!
        private static final String CACERTS_PASSWORD = "changeit";
    
        /**
         * Add a certificate to the cacerts keystore if it's not already included
         * 
         * @param alias The alias for the certificate, if added
         * @param certInputStream The certificate input stream
         * @throws KeyStoreException
         * @throws NoSuchAlgorithmException
         * @throws CertificateException
         * @throws IOException
         */
        public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream)
                throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
            //get default cacerts file
            final File cacertsFile = new File(System.getProperty("java.home") + CACERTS_PATH);
            if (!cacertsFile.exists()) {
                throw new FileNotFoundException(cacertsFile.getAbsolutePath());
            }
    
            //load cacerts keystore
            FileInputStream cacertsIs = new FileInputStream(cacertsFile);
            final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
            cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray());
            cacertsIs.close();
    
            //load certificate from input stream
            final CertificateFactory cf = CertificateFactory.getInstance("X.509");
            final Certificate cert = cf.generateCertificate(certInputStream);
            certInputStream.close();
    
            //check if cacerts contains the certificate
            if (cacerts.getCertificateAlias(cert) == null) {
                //cacerts doesn't contain the certificate, add it
                cacerts.setCertificateEntry(alias, cert);
                //write the updated cacerts keystore
                FileOutputStream cacertsOs = new FileOutputStream(cacertsFile);
                cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray());
                cacertsOs.close();
            }
        }
    }
    

    Use it like so:

    SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt"));
    

提交回复
热议问题