开发者

Java SSL与TLS客户端证书配置方式

目录
  • 一、TLS安全概念
    • (1)PKI
    • (2)CA
    • (3)https
    • (4)单向认证
    • (5)双向认证
    • (6)SSL 
    • (7)OpenSSL
    • (8)X.509
    • (9)PEM
    • (10)DER
    • (11)CRT
    • (12)CER
    • (13)KEY
    • (14)CSR
    • (15)PFX/P12
    • (16)JKS
  • 二、证书存储格式
    • 三、证书客户端设置
      • (1)单向认证
      • (2)双向认证
    • 总结

      一、TLS安全概念

      (1)PKI

      PKI是 Public Key Infrastructure的简称,意思是公钥基础设施。

      公钥基础设施是提供公钥加密和数字签名服务的系统或平台,目的是为了管理密钥和证书。通过证书和秘钥来确认通讯双方是否可信任。

      (2)CA

      CA是Certificate Authority的简称,即证书的签发机构,它是PKI的核心。

      正常情况来说,CA是具有权威性的机构,通过CA获取证书需要给钱。

      但是有的时候可能不想用CA机构的证书,又想要使用https站点,那么可能就需要自己生成证书,但是这种证书浏览器是认为不安全的,本文档后边的具体步骤即针对这种场景。

      (3)https

      https是http+ssl,通俗点说,就是采用http通讯的安全传输协议,用来保证http传输过程中数据的机密性、完整性和可靠性,ssl需要证书。

      (4)单向认证

      网络通讯是双向的,但是安全认证不一定都是双向。大多数情况下可能都是单向的,只需要客户端确认服务端是可靠的,而服务端不管客户端是否可靠。

      即客户端,比如浏览器会验证服javascript务端证书,服务端不需要客户端证书。

      (5)双向认证

      双向认证相对于单向认证,即客户端需要确认服务端是否可信,服务端也需要确认客户端是否可信。

      双方都要验证对方的证书

      (6)SSL 

       Secure Sockets Layer,一种加密协议规范,如https就使用它进行加解密

      (7)OpenSSL

      一种ssl规范的实现,可以帮助我们生成解析各类证书

      (8)X.509

      证书标准,比如证书应该包含哪些信息

      (9)PEM

      Privacy Enhanced Mail,一种编码格式,常用于Apache和Unix服务器,查看证书信息:openssl x509 -in certificate.pem -text -noout

      (10)DER

      Distinguished Encoding Rules,一种编码格式,常用于Java和Windows服务器,查看证书的信息:openssl x509 -in certificate.der -inform der -text -noout

      (11)CRT

      certificate,证书文件,常见于UNIX系统,大多应是PEM编码

      (12)CER

      certificate,证书文件,常见于Windows系统,大多应是DER编码.

      (13)KEY

      通常用来存放一个公钥或者私钥,查看不同编码格式文件内容

      (14)CSR

      Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,查看方法:openssl req -noout -text -in my.csr (DER格式同上后面加上-inform der)

      (15)PFX/P12

      predecessor of PKCS#12,对Unix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,因此这个文件包含了证书js及私钥。

      (16)JKS

      Java Key Storage,跟OpenSSL关系不大,Java的keytool工具可以将PFX转为JKS,也能直接生成JKS

      二、证书存储格式

      1、pem格式:pem、crt、key后缀。编码方式base64,key使用pkcs1、pkcs8格式存储

      2、p12(通用的证书存储格式)

      3、jks(java的证书存储格式,依赖jdk版本,小版本差异会报错)

      三、证书客户端设置

      KeyManager是提供客户端证书管理,TrustManager是信任服务端证书管理

      (1)单向认证

              CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
              FileInputStream caInputStream = new FileInputStream(caPath);
              List<X509Certificate> caList =  certificateFactory.generateCertificates(caInputStream).stream().map(v->
                      (X509Certificate)v).collect(Collectors.toList());
              KeyStore keystore = KeyStore.getInstance("JKS");
              keystore.load(androidnull, null);
              for(X509Certificate ca: caList)
                 keystore.setCertificateEntry(ca.getSubjectDN().getName(), ca);
              TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
              tmf.init(keystore);
       
              SSLContext context = SSLContext.getInstance("TLS");
              context.init(null, tmf.getTrustManagers(), new SecureRandom());

      (2)双向认证

         priv编程客栈ate void sslContext() {
             // 初始化密钥库
              KeyManagerFactory keyManagerFactory = KeyManagerFactory
                      .getInstancewww.devze.com("SunX509");
              KeyStore keyStore = getKeyStore("client.jks", "123456", "PKCS12");
              keyManagerFactory.init(keyStore, "123456".toCharArray());
              // 初始化信任库
              TrustManagerFactory trustManagerFactory = TrustManagerFactory
                      .getInstance("SunX509");
              KeyStore trustkeyStore = getKeyStore("server.jks", "123456", "JKS");
              trustManagerFactory.init(trustkeyStore);
              // 初始化SSL上下文
              SSLContext ctx = SSLContext.getInstance("SSL");
              ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
                      .getTrustManagers(), null);
       
          }
       
          private  KeyStore getKeyStore(String keyStorePath, String password, String type)
                  throws Exception {
       
              FileInputStream is = new FileInputStream(keyStorePath);
              KeyStore ks = KeyStore.getInstance(type);
              ks.load(is, password.toCharArray());
              is.close();
              return ks;
          }

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜