HTTPS

作者: 改名_f64e | 来源:发表于2019-09-26 20:26 被阅读0次
    //生成.jks秘钥
    keytool -genkey -keystore e:\file\a\server_ks.jks -storepass server_password -keyalg RSA -keypass server_password
    
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -genkey -keystore e:\file\a\server_ks.jks -storepass server_password -keyalg RSA -keypass server_password
    您的名字与姓氏是什么?
      [Unknown]:  panghu
    您的组织单位名称是什么?
      [Unknown]:  test
    您的组织名称是什么?
      [Unknown]:  test
    您所在的城市或区域名称是什么?
      [Unknown]:  shenzhen
    您所在的省/市/自治区名称是什么?
      [Unknown]:  guangdong
    该单位的双字母国家/地区代码是什么?
      [Unknown]:  86
    CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86是否正确?
      [否]:  y
    
    //生成证书
    keytool -export -keystore e:\file\a\server_ks.jks -storepass server_password -file e:\file\a\server.cer
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -export -keystore e:\file\a\server_ks.jks -storepass server_password -file e:\file\a\server.cer
    
    
    存储在文件 <e:\file\a\server.cer> 中的证书
    

    单向HTTPS验证

        public static void main(String[] args) {
            new Thread(new ServerOne()).start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(new ClientOne()).start();
        }
    
        public static class ServerOne implements Runnable {
            //SSL协议版本
            private static final String TLS = "TLSv1.2";
            //KeyStore的类型
            private static final String PROVIDER = "SunX509";
            private static final String STORE_TYPE = "JKS";
            //秘钥的路径
            private static final String KEY_STORE_NAME = "e:\\file\\a\\server_ks.jks";
            //Server的端口
            private static final int DEFAULT_PORT = 8090; //自定义端口
            //秘钥的密码
            private static final String SERVER_KEY_STORE_PASSWORD = "server_password"; //秘钥的密码
    
            @Override
            public void run() {
                try {
                    //获取SSLContext
                    SSLContext sslContext = SSLContext.getInstance(TLS);
                    //生成秘钥的manager
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
                    //加载秘钥
                    KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
                    keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), SERVER_KEY_STORE_PASSWORD.toCharArray());
    
                    //秘钥初始化
                    keyManagerFactory.init(keyStoreOne, SERVER_KEY_STORE_PASSWORD.toCharArray());
    
                    //初始化SSLContext
                    sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
                    //获取SSLContext的SocketFactory
                    SSLServerSocket sslServerSocket = 
                      (SSLServerSocket) sslContext.getServerSocketFactory()
                        .createServerSocket(DEFAULT_PORT);
                    //是否开启双向验证
                    sslServerSocket.setNeedClientAuth(false);
                    System.out.println("服务器已开启,等待连接 .....");
                    Socket accept = sslServerSocket.accept();
                    System.out.println("客户端 : " + accept.getInetAddress().getHostAddress());
    
                    InputStream inputStream = accept.getInputStream();
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(bytes)) != -1) {
                        System.out.println("服务器收到数据 : " + new String(bytes, 0, len));
                    }
                    inputStream.close();
                    accept.close();
                    sslServerSocket.close();
                    System.out.println("服务器关闭");
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (UnrecoverableKeyException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static class ClientOne implements Runnable {
            private static final String TLS = "TLSv1.2";
            private static final String PROVIDER = "SunX509";
            private static final String STORE_TYPE = "JKS";
            private static final String TRUST_STORE_NAME = "e:\\file\\a\\server.cer";
    
            @Override
            public void run() {
                try {
                    SSLContext sslContext = SSLContext.getInstance(TLS);
                    
                    //生成信任证书Manager,默认系统会信任CA机构颁发的证书,自定的证书需要手动的加载
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
                    KeyStore keyStore = KeyStore.getInstance(STORE_TYPE);
                    keyStore.load(null);
                    //这种方式加载需要知道证书的密码
                    //keyStore.load(new FileInputStream(TRUST_STORE_NAME),"password".toCharArray());
                    
                    //生成验证工厂
                    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                    //生成别名(可以随便填写)
                    String certificateAlias = Integer.toString(0);
                    //加载证书
                    keyStore.setCertificateEntry(
                      certificateAlias,
                      certificateFactory.generateCertificate(
                        new FileInputStream(TRUST_STORE_NAME)));//拷贝好的证书  
                    
                    //初始化
                    trustManagerFactory.init(keyStore);
                    //初始化
                    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
                    SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("192.168.0.10", 8090);
                    socket.startHandshake();
    
                    OutputStream outputStream = socket.getOutputStream();
                    outputStream.write("这是SSL测试".getBytes());
                    outputStream.flush();
    
                    outputStream.close();
                    socket.close();
                    System.out.println("客户端关闭");
    
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                }
            }
        }
    输出:
    服务器已开启,等待连接 .....
    客户端 : 192.168.0.10
    服务器收到数据 : 这是SSL测试
    客户端关闭
    服务器关闭
    

    双向HTTPS验证

    //生成client端的秘钥和证书文件
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -genkey -keystore e:\file\a\client_ks.jks -storepass client_password -keyalg RSA -keypass client_password
    您的名字与姓氏是什么?
      [Unknown]:  panghu
    您的组织单位名称是什么?
      [Unknown]:  test
    您的组织名称是什么?
      [Unknown]:  test
    您所在的城市或区域名称是什么?
      [Unknown]:  shenzhen
    您所在的省/市/自治区名称是什么?
      [Unknown]:  guangdong
    该单位的双字母国家/地区代码是什么?
      [Unknown]:  86
    CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86是否正确?
      [否]:  y
    
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -export -keystore e:\file\a\client_ks.jks -storepass client_password -file e:\file\a\client.cer
    存储在文件 <e:\file\a\client.cer> 中的证书
    
    //把server.cer证书添加到serverTrust_ks.jks文件中
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -import -keystore e:\file\a\serverTrust_ks.jks -storepass client -file e:\file\a\server.cer
    所有者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
    发布者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
    序列号: 5d765707
    有效期为 Mon Sep 23 18:33:19 CST 2019 至 Sun Dec 22 18:33:19 CST 2019
    证书指纹:
             MD5:  9E:9D:33:A2:3C:A7:E5:61:F1:41:A7:DE:DF:66:45:56
             SHA1: E8:D9:F9:F8:03:60:F0:A9:34:D5:1C:99:86:22:AA:B4:B3:61:66:B5
             SHA256: 6C:82:5F:9F:31:C3:32:EC:62:CE:6C:59:C7:13:C1:6A:95:5B:4C:55:63:D0:A1:CE:7A:4B:1A:ED:9A:D0:CF:20
    签名算法名称: SHA256withRSA
    主体公共密钥算法: 2048 位 RSA 密钥
    版本: 3
    
    扩展:
    
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: CC 01 50 17 30 85 97 C8   DC 17 F5 59 52 DE 5F 90  ..P.0......YR._.
    0010: 4A 47 13 E4                                        JG..
    ]
    ]
    
    是否信任此证书? [否]:  y
    证书已添加到密钥库中
    
    // 把client端证书添加到clientTrust_ks.jks文件中
    C:\Program Files\Java\jdk1.8.0_221\bin>keytool -import -keystore e:\file\a\clientTrust_ks.jks -storepass server -file e:\file\a\client.cer
    所有者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
    发布者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
    序列号: 2a332242
    有效期为 Mon Sep 23 19:06:09 CST 2019 至 Sun Dec 22 19:06:09 CST 2019
    证书指纹:
             MD5:  A2:E1:C3:1B:8B:F1:78:C4:7D:EE:65:72:DB:B9:23:01
             SHA1: 42:27:6B:B2:10:5F:80:75:D7:F5:D5:33:01:25:08:8C:33:C6:B4:76
             SHA256: BB:A9:6C:44:2D:A2:30:6F:01:71:42:6E:6B:3F:19:5C:77:8A:05:79:9F:03:0E:42:E8:2E:A2:3C:47:E9:F6:E0
    签名算法名称: SHA256withRSA
    主体公共密钥算法: 2048 位 RSA 密钥
    版本: 3
    
    扩展:
    
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: 16 AB 67 DE 94 D4 8C 05   56 88 91 72 98 9A D4 FD  ..g.....V..r....
    0010: 96 16 C4 F3                                        ....
    ]
    ]
    
    是否信任此证书? [否]:  y
    证书已添加到密钥库中
    
    new Thread(new Server()).start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    new Thread(new Client()).start();
    
    public static class Server implements Runnable {
            private static final String TLS = "TLSv1.2";
            private static final String PROVIDER = "SunX509";
            private static final String STORE_TYPE = "JKS";
            private static final String KEY_STORE_NAME = "e:\\file\\a\\server_ks.jks";
            private static final String TRUST_STORE_NAME = "e:\\file\\a\\clientTrust_ks.jks";
            private static final int DEFAULT_PORT = 8090; //自定义端口
            private static final String SERVER_KEY_STORE_PASSWORD = "server_password"; //密码
            private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "server";//密码
    
            @Override
            public void run() {
                try {
                    SSLContext sslContext = SSLContext.getInstance(TLS);
                    //加载server端的秘钥
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
                    //加载信任的证书
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
                    KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
                    KeyStore keyStoreTwo = KeyStore.getInstance(STORE_TYPE);
                    keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), SERVER_KEY_STORE_PASSWORD.toCharArray());
                    keyStoreTwo.load(new FileInputStream(TRUST_STORE_NAME), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
                    keyManagerFactory.init(keyStoreOne, SERVER_KEY_STORE_PASSWORD.toCharArray());
                    trustManagerFactory.init(keyStoreTwo);
    
                    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
                    SSLServerSocket sslServerSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
                    // 开启双向验证
                    sslServerSocket.setNeedClientAuth(true);
                    System.out.println("服务器已开启,等待连接 .....");
                    Socket accept = sslServerSocket.accept();
                    System.out.println("客户端 : " + accept.getInetAddress().getHostAddress());
    
                    InputStream inputStream = accept.getInputStream();
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(bytes)) != -1) {
                        System.out.println("服务器收到数据 : " + new String(bytes, 0, len));
                    }
                    inputStream.close();
                    accept.close();
                    sslServerSocket.close();
                    System.out.println("服务器关闭");
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (UnrecoverableKeyException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static class Client implements Runnable {
            private static final String TLS = "TLSv1.2";
            private static final String PROVIDER = "SunX509";
            private static final String STORE_TYPE = "JKS";
            private static final String KEY_STORE_NAME = "e:\\file\\a\\client_ks.jks";
            private static final String TRUST_STORE_NAME = "e:\\file\\a\\serverTrust_ks.jks";
            private static final String CLIENT_KEY_STORE_PASSWORD = "client_password"; //密码
            private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "client";//密码
    
            @Override
            public void run() {
                try {
                    SSLContext sslContext = SSLContext.getInstance(TLS);
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
    
                    KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
                    KeyStore keyStoreTwo = KeyStore.getInstance(STORE_TYPE);
    
                    //加载client端的秘钥
                    keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), CLIENT_KEY_STORE_PASSWORD.toCharArray());
                    //信任证书
                    keyStoreTwo.load(new FileInputStream(TRUST_STORE_NAME), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
    
                    keyManagerFactory.init(keyStoreOne, CLIENT_KEY_STORE_PASSWORD.toCharArray());
                    trustManagerFactory.init(keyStoreTwo);
                    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
                    SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("192.168.0.10", 8090);
                    socket.startHandshake();
    
                    OutputStream outputStream = socket.getOutputStream();
                    outputStream.write("这是SSL测试".getBytes());
                    outputStream.flush();
    
                    outputStream.close();
                    socket.close();
                    System.out.println("客户端关闭");
    
    
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (UnrecoverableKeyException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                }
            }
        }
    
    

    相关文章

      网友评论

          本文标题:HTTPS

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