PKI、TLS、证书概念整理
1. PKI
Public Key Infrastructure - 公钥基础设施,这个名字,直译出来总觉得少点味,尤其是对于非安全领域,在接触到这个概念时,第一感觉它只是个“设施”,主要是用来管理“公钥”的,让人非常的疑惑。这类专有名词为什么不能稍微意译一下呢?
PKI是一个体系,一个架构,一系列东西的集合,这个集合中规定了各种元素,元素的作用,元素和元素之间的通讯协议等等。在这个集合所构成的体系之下,能够保证集合中的两个节点的通讯是安全的。而我们广袤的互联网所使用的PKI,就是一种基于可信第三方(CA,Certificate Authority)的PKI。下文所说的PKI如无特殊说明,就是指基于可信第三方的PKI。
2. HTTP over TLS
HTTPS的交互过程网络上资料很多,不再做赘述。比较令我好奇的是,当进行双向校验时,客户端如何选择证书?
在一个TLS建链过程中,有两个角色,一个客户端(client)主动发起,一个服务端(server)。
服务端必须有秘钥对(证书+私钥)。用于认证以及用于对称秘钥加密。如果服务端不校验客户端,同时客户端也不校验服务端证书,那客户端可以不配置任何证书相关的东西。如果服务端需要校验客户端,则需要有CA,用来验证客户端证书是否为其签发。当客户端配置的方式为keystore时,其中可能存在许多对秘钥对,客户端如何选择用哪个密钥对来通信呢?从协议交互图中看出来,有一个5过程,该过程为服务端要求客户端提供证书。
该博客中记录了TLS中,Certificate Request的内容 :https://blog.csdn.net/mrpre/article/details/77868263
3. 证书(X509)、秘钥对
-
X.509,证书标准,定义证书格式,遵循ASN.1规范。X.509定义的证书结构:
-
Version Number,版本
-
Serial Number,序列号
-
Signature Algorithm ID,签名算法ID
-
Issuer Name,颁发者
-
Validity period,有效期
- Not Before
- Not After
-
Subject name,使用者
-
Subject Public Key Info,公钥信息
- Public Key Algorithm
- Subject Public Key
-
Issuer Unique Identifier (optional),颁发者唯一ID
-
Subject Unique Identifier (optional),使用者唯一ID
-
Extensions (optional),扩展字段
- …
-
Certificate Signature Algorithm,证书签名算法
-
Certificate Signature,证书签名
#使用openssl查看一张证书,此证书选自jdk中默认证书中的一张 openssl x509 -text -in actalisauthenticationrootca.cer -noout
Certificate: Data: Version: 3 (0x2) Serial Number: 6271844772424770508 (0x570a119742c4e3cc) Signature Algorithm: sha256WithRSAEncryption Issuer: C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication Root CA Validity Not Before: Sep 22 11:22:02 2011 GMT Not After : Sep 22 11:22:02 2030 GMT Subject: C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication Root CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:a7:c6:c4:a5:29:a4:2c:ef:e5:18:c5:b0:50:a3: ...省略 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 52:D8:88:3A:C8:9F:78:66:ED:89:F3:7B:38:70:94:C9:02:02:36:D0 X509v3 Basic Constraints: critical CA:TRUE X509v3 Authority Key Identifier: keyid:52:D8:88:3A:C8:9F:78:66:ED:89:F3:7B:38:70:94:C9:02:02:36:D0 X509v3 Key Usage: critical Certificate Sign, CRL Sign Signature Algorithm: sha256WithRSAEncryption 0b:7b:72:87:c0:60:a6:49:4c:88:58:e6:1d:88:f7:14:64:48: ...省略
-
-
证书类型:
- DV,domain validated,域名验证,网站一般都使用DV
- OV,organization validated,组织验证
- EV,extended validated,扩展验证
-
秘钥对,证书+私钥
4. Practice
JDK/JRE默认证书路径,这就是个jks文件:
$JAVA_HOME/lib/security/cacerts
确认某个站点发送了证书:
openssl s_client -showcerts -connect shareif.cn:443
~/Projects ᐅ openssl s_client -showcerts -connect shareif.cn:443
CONNECTED(00000005)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = www.github.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
-----BEGIN CERTIFICATE-----
...省略
-----END CERTIFICATE-----
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
-----BEGIN CERTIFICATE-----
...省略
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 3674 bytes and written 289 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: D11A4DD2C801FADA75D685893D661809EBCD8D1D071203A0681DC57959B69670
Session-ID-ctx:
Master-Key: 9CFDC956C3EB2BCCD5693041A34A92F43755D88172A5B1E72AFED2A77273F4593A3B0D1F52BA2A8F29A0B5AECF112F09
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - de 13 86 32 27 39 ff 04-80 a1 38 9b 76 32 8e d6 ...2'9....8.v2..
0010 - 5f 7b 98 f4 1d 26 1e bf-03 ae 69 5d 3c fc 71 9c _{...&....i]<.q.
0020 - 09 77 f5 10 e7 c0 d2 b8-1c 6b f1 51 5d 26 25 3d .w.......k.Q]&%=
0030 - f9 c6 be 79 53 b0 37 0c-74 8a e8 72 67 00 72 aa ...yS.7.t..rg.r.
0040 - 2a 05 d7 07 fa 26 ca e4-ab c1 92 45 2f 01 6b a0 *....&.....E/.k.
0050 - d9 14 4f bc 6c 85 43 c1-74 1f dd d9 56 b4 bf 8d ..O.l.C.t...V...
0060 - 16 d1 fa f0 68 b4 fd 4b-bd bd 2f e1 7b bc 16 cc ....h..K../.{...
0070 - 92 26 8c 2f b2 55 25 b4-79 b2 ab 34 2a 1a 1f f6 .&./.U%.y..4*...
0080 - 85 a8 8d 9b 63 3f cd f4-d2 60 5c 2c 10 ac 99 06 ....c?...`\,....
0090 - 1d 02 bc 78 ca 37 d2 65-46 7f 16 56 12 b1 e2 5f ...x.7.eF..V..._
Start Time: 1586685050
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
Java代码扫描KeyStore中的证书有效期
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream(new File(PATH)), PASSWORD.toCharArray());
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);
try {
cert.checkValidity(DateTime.now().toDate());
} catch (CertificateExpiredException cee) {
System.out.println("cert is expired.")
} catch (CertificateNotYetValidException cnyve) {
System.out.println("certi is not yet valid")
}
}
5. 参考
- PKI from wikipedia
- X.509 from wikipedia
- 《HTTPS权威指南》
- Java Developer Guide to SSL VPN needed