美文网首页
java关于https证书认证及生成

java关于https证书认证及生成

作者: hao_yu | 来源:发表于2020-09-11 13:58 被阅读0次

    1、关于http及https相关内容,参考:
    https://blog.csdn.net/xiaoming100001/article/details/81109617
    2、因为要访问的https网站非授信网站,故需要获取其证书,未找到直接获取的办法
    注:网页直接输入的https://host,然后F12获取证书,导致证书无法获取到,后来发现使用https://host:port的方式才可以获取到(此服务的端口不是默认的443),故证书下载后无需使用下面的java代码,直接导入证书即可。
    3、下面是java代码(参考网上找到的实现):

    
    /*
     * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *   - Redistributions of source code must retain the above copyright
     *     notice, this list of conditions and the following disclaimer.
     *
     *   - Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *
     *   - Neither the name of Sun Microsystems nor the names of its
     *     contributors may be used to endorse or promote products derived
     *     from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.security.KeyStore;
    import java.security.MessageDigest;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLException;
    import javax.net.ssl.SSLSocket;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    /**
     * 导入证书命令:
     * keytool -import -v -trustcacerts -alias ${alias} -file "${file路径}" -storepass changeit -keystore cacerts
     * keytool -delete -alias {alias} -keystore cacerts -storepass changeit
     * keytool -list -keystore cacerts -storepass changeit
     * keytool -export -alias  {alias} -file  {file_name} -keystore cacerts -storepass changeit
     */
    public class InstallCert {
    
        static String host = "xxx.com";
        static int port = 7777;
        //证书密码
        static char[] passphrase = "changeit".toCharArray();
    
        //生成的证书文件名
        static String certName = "jssecacerts";
    
        public static void main(String[] args) throws Exception {
    
            File file = buildFile(certName);
            System.out.println("Loading KeyStore " + file + "...");
            InputStream in = new FileInputStream(file);
            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(in, passphrase);
            in.close();
    
            SSLContext context = SSLContext.getInstance("TLS");
            TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(ks);
            X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                    .getTrustManagers()[0];
            SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
            context.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory factory = context.getSocketFactory();
    
            System.out.println("Opening connection to " + host + ":" + port + "...");
            SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
            socket.setSoTimeout(10000);
            try {
                System.out.println("Starting SSL handshake...");
                socket.startHandshake();
                socket.close();
                System.out.println();
                System.out.println("No errors, certificate is already trusted");
            } catch (SSLException e) {
                System.out.println();
                e.printStackTrace(System.out);
            }
    
            X509Certificate[] chain = tm.chain;
            if (chain == null) {
                System.out.println("Could not obtain server certificate chain");
                return;
            }
    
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    System.in));
    
            System.out.println();
            System.out.println("Server sent " + chain.length + " certificate(s):");
            System.out.println();
            MessageDigest sha1 = MessageDigest.getInstance("SHA1");
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            for (int i = 0; i < chain.length; i++) {
                X509Certificate cert = chain[i];
                System.out.println(" " + (i + 1) + " Subject " + cert.getSubjectDN());
                System.out.println("   Issuer  " + cert.getIssuerDN());
                sha1.update(cert.getEncoded());
                System.out.println("   sha1    " + toHexString(sha1.digest()));
                md5.update(cert.getEncoded());
                System.out.println("   md5     " + toHexString(md5.digest()));
                System.out.println();
            }
    
            System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
            String line = reader.readLine().trim();
            int k;
            try {
                k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
            } catch (NumberFormatException e) {
                System.out.println("KeyStore not changed");
                return;
            }
    
            X509Certificate cert = chain[k];
            String alias = host + "-" + (k + 1);
            ks.setCertificateEntry(alias, cert);
    
            OutputStream out = new FileOutputStream(certName);
            ks.store(out, passphrase);
            out.close();
    
            System.out.println();
            System.out.println(cert);
            System.out.println();
            System.out.println("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'");
        }
    
        private static File buildFile(String certName) {
            File file = new File(certName);
            if (!file.isFile()) {
                char SEP = File.separatorChar;
                File dir = new File(System.getProperty("java.home") + SEP + "lib"
                        + SEP + "security");
                file = new File(dir, certName);
                if (!file.isFile()) {
                    file = new File(dir, "cacerts");
                }
            }
            return file;
        }
    
        private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
    
        private static String toHexString(byte[] bytes) {
            StringBuilder sb = new StringBuilder(bytes.length * 3);
            for (int b : bytes) {
                b &= 0xff;
                sb.append(HEXDIGITS[b >> 4]);
                sb.append(HEXDIGITS[b & 15]);
                sb.append(' ');
            }
            return sb.toString();
        }
    
        private static class SavingTrustManager implements X509TrustManager {
    
            private final X509TrustManager tm;
            private X509Certificate[] chain;
    
            SavingTrustManager(X509TrustManager tm) {
                this.tm = tm;
            }
    
            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                throw new UnsupportedOperationException();
            }
    
            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
                this.chain = chain;
                tm.checkServerTrusted(chain, authType);
            }
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
                // throw new UnsupportedOperationException();注释该行,用上面这行替代即可
            }
        }
    
    }
    

    4、生成证书后,使用如下命令导出证书:

    keytool -export -alias ${file_name} -file test.crt -keystore cacerts -storepass changeit
    

    当然,若是java程序使用的话,就把证书jssecacerts copy到${JAVA_HOME}/lib/security下即可

    相关文章

      网友评论

          本文标题:java关于https证书认证及生成

          本文链接:https://www.haomeiwen.com/subject/adovektx.html