如何生成本地SSL,并开发SSL下的socket

网上讲解SSL证书的文章太多了。所以这里就不在跟风赘述SSL证书,签名,加密等原理了。本章核心只有一个,就是实战。从0开始讲述如何生成自己的SSL证书,以及如何开发SSL加密的 java socket通信。 代码在pur-ssl-socket 文章结构如下:

  1. 得到一个本地SSL证书
  2. 使用java 开发socket的server段,并用SSL证书做加密处理
  3. 使用java开发socket的client段,并用SSL证书做加密处理

得到一个本地SSL证书

如果想生成一个jdk识别的证书,可以有两种方法:

  1. 使用jdk的 keytool生成一个证书
  2. 使用keytool导入一个已经存在的CA机构的crt证书
生成自己的SSL证书
     # 会提示输入密码,这里记好自己输入的密码。然后一路回车,知道最后敲yes
    keytool -genkey -alias moheqionglin -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
TIPS: 输入如下命令,然后记住证书的关键属性信息,这些信息会涉及到后面项目汇总的配置

    keytool -list -keystore keystore.p12

    #非常重要,后面程序中会使用
    Keystore type: JKS
      #非常重要,后面程序中会使用
    Keystore provider: SUN

    Your keystore contains 1 entry

    moheqionglin, Jan 16, 2018, PrivateKeyEntry,
    Certificate fingerprint (SHA1):     F6:26:18:EB:F2:12:04:82:86:04:10:99:E5:20:B1:BD:E6:91:25:B9

导入已有的证书

 keytool -import -file ~/Desktop/gsorganizationvalsha2g2r1.crt  -keystore ~/Desktop/javassl

结果如下:

Enter keystore password:  
Re-enter new password: 
Owner: CN=GlobalSign Organization Validation CA - SHA256 - G2, O=GlobalSign nv-sa, C=BE
Issuer: CN=GlobalSign Root CA, OU=Root CA, O=GlobalSign nv-sa, C=BE
Serial number: 40000000001444ef04247
Valid from: Thu Feb 20 18:00:00 CST 2014 until: Tue Feb 20 18:00:00 CST 2024
Certificate fingerprints:
     MD5:  D3:E8:70:6D:82:92:AC:E4:DD:EB:F7:A8:BB:BD:56:6B
     SHA1: 90:2E:F2:DE:EB:3C:5B:13:EA:4C:3D:51:93:62:93:09:E2:31:AE:55
     SHA256: 74:EF:33:5E:5E:18:78:83:07:FB:9D:89:CB:70:4B:EC:11:2A:BD:23:48:7D:BF:F4:1C:4D:ED:50:70:F2:41:D9
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions: 

#1: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
  [
   accessMethod: ocsp
   accessLocation: URIName: http://ocsp.globalsign.com/rootr1
]
]

#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 60 7B 66 1A 45 0D 97 CA   89 50 2F 7D 04 CD 34 A8  `.f.E....P/...4.
0010: FF FC FD 4B                                        ...K
]
]

#3: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:0
]

#4: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://crl.globalsign.net/root.crl]
]]

#5: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
  [CertificatePolicyId: [2.5.29.32.0]
[PolicyQualifierInfo: [
  qualifierID: 1.3.6.1.5.5.7.2.1
  qualifier: 0000: 16 26 68 74 74 70 73 3A   2F 2F 77 77 77 2E 67 6C  .&https://www.gl
0010: 6F 62 61 6C 73 69 67 6E   2E 63 6F 6D 2F 72 65 70  obalsign.com/rep
0020: 6F 73 69 74 6F 72 79 2F                            ository/

]]  ]
]

#6: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  Key_CertSign
  Crl_Sign
]

#7: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 96 DE 61 F1 BD 1C 16 29   53 1C C0 CC 7D 3B 83 00  ..a....)S....;..
0010: 40 E6 1A 7C                                        @...
]
]

Trust this certificate? [no]:  y
Certificate was added to keystore

这个时候jdk支持的证书已经生成了。我们可以使用keytool -list查看生成的证书的基本配置信息。

keytool -list -keystore ~/Desktop/javassl 
Enter keystore password:  

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

mykey, Mar 5, 2018, trustedCertEntry, 
Certificate fingerprint (SHA1): 90:2E:F2:DE:EB:3C:5B:13:EA:4C:3D:51:93:62:93:09:E2:31:AE:55

使用java 开发socket的server段,并用SSL证书做加密处理


     System.out.println("等待客户端连接...");
        final String imageResource = "/keystore.p12";
        final URL url = SslSocketServer.class.getResource(imageResource);
        InputStream stream = getClass().getResourceAsStream(imageResource);
        char[] password = "123456".toCharArray();

        //KeyStore用于存放证书,创建对象时 指定交换数字证书的加密标准
        KeyStore keyStore = KeyStore.getInstance("JKS"); //KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(stream, password);
        stream.close();

        //KeyManager选择证书证明自己的身份
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, password);
        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

        //TrustManager决定是否信任对方的证书
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

        SSLContext context = SSLContext.getInstance("SSL");
        context.init(keyManagers, trustManagers, null);
        SSLServerSocketFactory factory = context.getServerSocketFactory();
        SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(3344);
        SSLSocket socket = (SSLSocket) serverSocket.accept();

        System.out.println("有客户端连接");
        System.out.println("向客户端输出信息");
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
        writer.write("hello world\r\n");
        writer.write("\r\n");
        writer.flush();
        System.out.println("输出结束");
        socket.close();
        serverSocket.close();

使用java开发socket的client段,并用SSL证书做加密处理



     System.out.println("准备连接服务端");
            final String imageResource = "/keystore.p12";
            final URL url = SslSocketServer.class.getResource(imageResource);
            InputStream stream = getClass().getResourceAsStream(imageResource);
            char[] password = "123456".toCharArray();

            //指定交换数字证书的加密标准
            KeyStore keyStore = KeyStore.getInstance("JKS");//KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(stream, password);
            stream.close();

            //TrustManager决定是否信任对方的证书
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, trustManagers, null);
            SSLSocketFactory factory = context.getSocketFactory();
            SSLSocket socket = (SSLSocket) factory.createSocket("localhost", 3344);

            InputStream inputStream = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String str = null;
            while ((str = reader.readLine()) != null) {
                if (str.equals(""))
                    break;
                System.out.println(str);
            }
            socket.close();
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
慷慨打赏