什么是OCSP
OCSP(Online Certificate Status Protocol)即在线证书状态协议,是一个互联网协议,用于获取符合X.509标准的数字证书的状态。OCSP是维护服务器和其它网络资源安全性的两种普遍模式之一。OCSP协议的产生是用于在公钥基础设施(PKI)体系中替代证书吊销列表(CRL)来查询数字证书的状态,当用户试图访问一个服务器时,在线证书状态协议发送一个对于证书状态信息的请求。服务器回复一个“有效”、“过期”或“未知”的响应。
关于OCSP的定义就介绍这么多,以及OCSP、OCSP Stapling和CRL的关系和区别在这篇文章中也就不多说。
OCSP代码实现
直接上代码
package org.example;
import cn.hutool.core.io.IoUtil;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.ocsp.CertificateID;
import org.bouncycastle.cert.ocsp.OCSPReq;
import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
import org.bouncycastle.cert.ocsp.OCSPResp;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.*;
import java.util.Collections;
public class OCSPVaild {
public static void main(String[] args) throws Exception{
// 加载待验证的证书
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream inputStream = new FileInputStream("C:\\Users\\1\\Desktop\\baidu.crt");
X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
// 加载待验证证书的上级证书
inputStream = new FileInputStream("C:\\Users\\1\\Desktop\\issuing_ca.crt");
X509Certificate issurCert = (X509Certificate) cf.generateCertificate(inputStream);
String url = null;
TBSCertificate tbs = TBSCertificate.getInstance(cert.getTBSCertificate());
Extensions extensions = tbs.getExtensions();
AuthorityInformationAccess access = AuthorityInformationAccess.fromExtensions(extensions);
AccessDescription[] descs = access.getAccessDescriptions();
for (AccessDescription desc : descs) {
//获取特定OID的属性值
if (desc.getAccessMethod().getId().equalsIgnoreCase("1.3.6.1.5.5.7.48.1")) {
url = desc.getAccessLocation().getName().toString();
}
}
System.out.println(url);
OCSPReq ocspReq = buildOCSPRequest(cert, issurCert);
OCSPResp ocspResp = requestOCSPResponse(url, ocspReq);
System.out.println(ocspResp.getStatus());
}
public static OCSPReq buildOCSPRequest(final X509Certificate x509Certificate, final X509Certificate issuerX509Certificate) {
try {
CertificateID certId = new CertificateID(
(new BcDigestCalculatorProvider())
.get(CertificateID.HASH_SHA1),
new X509CertificateHolder(issuerX509Certificate.getEncoded()),
x509Certificate.getSerialNumber());
OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder();
ocspReqBuilder.addRequest(certId);
OCSPReq ocspReq = ocspReqBuilder.build();
return ocspReq;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static OCSPResp requestOCSPResponse(String url, OCSPReq ocspReq) throws IOException, MalformedURLException {
byte[] ocspReqData = ocspReq.getEncoded();
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
try {
con.setRequestProperty("Content-Type", "application/ocsp-request");
con.setRequestProperty("Accept", "application/ocsp-response");
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
OutputStream out = con.getOutputStream();
try {
out.write(ocspReqData);
out.flush();
} finally {
out.close();
}
byte[] responseBytes = IoUtil.readBytes(con.getInputStream());
OCSPResp ocspResp = new OCSPResp(responseBytes);
return ocspResp;
} finally {
if (con != null) {
con.disconnect();
}
}
}
}
完整的代码已经贴出来了,有需要的直接复制就可以了,我也是在网上找的,具体是哪篇给忘记了~
其中baidu.crt为待验证的证书,这是从百度的首页获取的证书,中间证书为GlobalSign的中间证书。
先看一下两张证书的结构
baidu.crt
$ openssl x509 -in baidu.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
55:e6:ac:ae:d1:f8:a4:30:f9:a9:38:c5
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
Validity
Not Before: Jul 6 01:51:06 2023 GMT
Not After : Aug 6 01:51:05 2024 GMT
Subject: C = CN, ST = beijing, L = beijing, O = "Beijing Baidu Netcom Science Technology Co., Ltd", CN = baidu.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:bb:04:bb:84:76:58:07:b4:5a:88:54:e0:6a:56:
bc:e5:d4:8d:3e:1e:b9:28:e0:d7:01:8f:38:2b:41:
b2:59:7d:f0:ac:27:b4:26:24:14:38:fe:4c:ea:3b:
49:51:f7:e9:5b:40:f7:3f:a6:c8:da:0f:02:6e:25:
8b:47:91:b8:2e:9e:00:21:19:1d:18:00:fc:de:04:
fd:26:79:39:5d:f2:90:bc:80:9d:a8:7c:b2:91:89:
89:d8:40:2f:e5:d2:a7:f3:5e:6d:48:2b:c5:1f:0a:
b1:e0:8e:8c:76:ff:bc:d1:67:0a:d2:49:d6:09:ee:
26:03:02:f3:cc:cd:ea:8a:d5:31:a8:2d:8f:03:fd:
5e:fc:e4:3a:c6:89:67:99:4c:ce:98:6d:fa:84:0d:
0e:53:8b:e6:63:52:c5:9b:4a:a9:ab:a3:22:35:99:
0d:ee:19:ff:9b:2d:f5:a4:77:f2:ec:10:80:f4:ab:
82:b9:d1:7e:36:1f:0e:9f:9b:19:a0:f5:c3:57:dd:
88:bb:ce:e1:90:9c:3f:4b:ba:dd:3a:a9:41:b3:dd:
86:4d:c2:c2:b7:e8:ff:37:13:c0:04:89:43:44:38:
11:e6:a3:96:f7:09:22:21:2f:2c:4e:0e:7e:e5:d8:
5c:bb:00:44:5b:af:de:e4:b3:b0:f0:3c:b6:38:45:
49:5d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
Authority Information Access:
CA Issuers - URI:http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt
OCSP - URI:http://ocsp.globalsign.com/gsrsaovsslca2018
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.4146.1.20
CPS: https://www.globalsign.com/repository/
Policy: 2.23.140.1.2.2
X509v3 Basic Constraints:
CA:FALSE
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.globalsign.com/gsrsaovsslca2018.crl
X509v3 Subject Alternative Name:
DNS:baidu.com, DNS:baifubao.com, DNS:www.baidu.cn, DNS:www.baidu.com.cn, DNS:mct.y.nuomi.com, DNS:apollo.auto, DNS:dwz.cn, DNS:*.baidu.com, DNS:*.baifubao.com, DNS:*.baidustatic.com, DNS:*.bdstatic.com, DNS:*.bdimg.com, DNS:*.hao123.com, DNS:*.nuomi.com, DNS:*.chuanke.com, DNS:*.trustgo.com, DNS:*.bce.baidu.com, DNS:*.eyun.baidu.com, DNS:*.map.baidu.com, DNS:*.mbd.baidu.com, DNS:*.fanyi.baidu.com, DNS:*.baidubce.com, DNS:*.mipcdn.com, DNS:*.news.baidu.com, DNS:*.baidupcs.com, DNS:*.aipage.com, DNS:*.aipage.cn, DNS:*.bcehost.com, DNS:*.safe.baidu.com, DNS:*.im.baidu.com, DNS:*.baiducontent.com, DNS:*.dlnel.com, DNS:*.dlnel.org, DNS:*.dueros.baidu.com, DNS:*.su.baidu.com, DNS:*.91.com, DNS:*.hao123.baidu.com, DNS:*.apollo.auto, DNS:*.xueshu.baidu.com, DNS:*.bj.baidubce.com, DNS:*.gz.baidubce.com, DNS:*.smartapps.cn, DNS:*.bdtjrcv.com, DNS:*.hao222.com, DNS:*.haokan.com, DNS:*.pae.baidu.com, DNS:*.vd.bdstatic.com, DNS:*.cloud.baidu.com, DNS:click.hm.baidu.com, DNS:log.hm.baidu.com, DNS:cm.pos.baidu.com, DNS:wn.pos.baidu.com, DNS:update.pan.baidu.com
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Authority Key Identifier:
keyid:F8:EF:7F:F2:CD:78:67:A8:DE:6F:8F:24:8D:88:F1:87:03:02:B3:EB
X509v3 Subject Key Identifier:
ED:73:AB:F9:20:BE:7A:19:9F:59:1F:B2:9F:F2:3F:2F:3F:91:84:12
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : 48:B0:E3:6B:DA:A6:47:34:0F:E5:6A:02:FA:9D:30:EB:
1C:52:01:CB:56:DD:2C:81:D9:BB:BF:AB:39:D8:84:73
Timestamp : Jul 6 01:51:12.385 2023 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:21:00:ED:1A:F4:5F:4A:CC:2B:FF:57:DF:E5:
B8:CB:F9:24:5C:B7:7E:14:7B:A3:DA:46:C0:D8:BC:68:
69:89:87:A3:83:02:20:5F:F6:82:83:D3:A0:E4:46:5B:
54:BA:3E:66:CA:D4:F6:CD:C8:26:EB:18:CD:96:23:01:
22:6C:CC:4C:F0:67:5A
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : EE:CD:D0:64:D5:DB:1A:CE:C5:5C:B7:9D:B4:CD:13:A2:
32:87:46:7C:BC:EC:DE:C3:51:48:59:46:71:1F:B5:9B
Timestamp : Jul 6 01:51:12.413 2023 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:46:02:21:00:BD:1D:C3:18:2A:7E:78:1E:2B:D2:6E:
11:F4:C2:E5:AD:C1:36:87:62:DB:88:BC:90:FC:22:13:
C5:FB:32:7D:FE:02:21:00:80:8C:9E:88:86:A1:C7:3A:
14:62:0C:21:89:8C:77:BA:7B:24:94:97:31:90:A9:15:
74:A2:6C:2C:33:83:52:2D
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : DA:B6:BF:6B:3F:B5:B6:22:9F:9B:C2:BB:5C:6B:E8:70:
91:71:6C:BB:51:84:85:34:BD:A4:3D:30:48:D7:FB:AB
Timestamp : Jul 6 01:51:11.703 2023 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:44:02:20:54:6D:6A:69:EA:E0:A3:58:F9:17:D5:AD:
E4:77:36:A3:7B:33:8D:C3:95:30:76:7E:E5:FB:1C:A9:
8C:4E:9B:77:02:20:1B:61:8A:F2:91:FE:E5:4A:99:4D:
32:B1:37:2A:82:46:88:89:0D:7E:EB:01:7C:F1:3B:6D:
9A:21:19:24:05:C0
Signature Algorithm: sha256WithRSAEncryption
19:5a:67:50:43:b1:ac:7a:93:a8:68:18:72:8b:40:7e:a6:75:
de:ac:21:fc:c9:41:16:20:4b:f3:8c:0b:b9:47:45:ae:f8:5d:
79:f6:43:35:26:01:98:f0:b9:86:3e:29:01:f1:df:b0:72:b5:
ae:78:d2:df:61:b6:78:67:8a:c9:77:9a:de:e0:e4:41:2f:9c:
1e:e5:3b:7c:97:3f:42:2f:ad:e3:49:7f:9d:2b:02:88:90:69:
25:03:01:14:b9:b5:cb:0f:59:3d:2d:97:3d:02:d5:51:90:69:
0c:81:10:22:da:c6:51:ef:48:0c:d2:4f:de:61:f2:6a:87:15:
a5:6d:71:8e:37:02:a2:85:0f:1e:19:75:a3:80:2e:6a:1a:a2:
02:8c:2f:ec:bd:3d:81:03:3f:8a:c0:a0:e6:b4:0e:08:57:cb:
00:1c:8a:b7:1b:8f:38:71:9a:8d:c0:71:0c:3f:bc:d4:be:56:
9d:f7:18:c1:aa:be:e4:df:1a:86:e2:62:6f:23:86:30:54:78:
2d:47:1f:b4:ad:05:29:73:24:98:14:a0:19:c0:02:fd:90:90:
4e:62:5c:e8:4d:31:89:c3:e8:8b:9e:73:59:3b:98:91:ca:47:
a5:05:5b:c5:1e:8f:85:39:0e:ce:b5:26:0a:80:4e:9f:08:4a:
11:49:13:63
issuing_ca.crt
$ openssl x509 -in issuing_ca.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
01:ee:5f:22:1d:fc:62:3b:d4:33:3a:85:57
Signature Algorithm: sha256WithRSAEncryption
Issuer: OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
Validity
Not Before: Nov 21 00:00:00 2018 GMT
Not After : Nov 21 00:00:00 2028 GMT
Subject: C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:a7:5a:c9:d5:0c:18:21:00:23:d5:97:0f:eb:ae:
dd:5c:68:6b:6b:8f:50:60:13:7a:81:cb:97:ee:8e:
8a:61:94:4b:26:79:f6:04:a7:2a:fb:a4:da:56:bb:
ee:a0:a4:f0:7b:8a:7f:55:1f:47:93:61:0d:6e:71:
51:3a:25:24:08:2f:8c:e1:f7:89:d6:92:cf:af:b3:
a7:3f:30:ed:b5:df:21:ae:fe:f5:44:17:fd:d8:63:
d9:2f:d3:81:5a:6b:5f:d3:47:b0:ac:f2:ab:3b:24:
79:4f:1f:c7:2e:ea:b9:15:3a:7c:18:4c:69:b3:b5:
20:59:09:5e:29:c3:63:e6:2e:46:5b:aa:94:90:49:
0e:b9:f0:f5:4a:a1:09:2f:7c:34:4d:d0:bc:00:c5:
06:55:79:06:ce:a2:d0:10:f1:48:43:e8:b9:5a:b5:
95:55:bd:31:d2:1b:3d:86:be:a1:ec:0d:12:db:2c:
99:24:ad:47:c2:6f:03:e6:7a:70:b5:70:cc:cd:27:
2c:a5:8c:8e:c2:18:3c:92:c9:2e:73:6f:06:10:56:
93:40:aa:a3:c5:52:fb:e5:c5:05:d6:69:68:5c:06:
b9:ee:51:89:e1:8a:0e:41:4d:9b:92:90:0a:89:e9:
16:6b:ef:ef:75:be:7a:46:b8:e3:47:8a:1d:1c:2e:
a7:4f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
F8:EF:7F:F2:CD:78:67:A8:DE:6F:8F:24:8D:88:F1:87:03:02:B3:EB
X509v3 Authority Key Identifier:
keyid:8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC
Authority Information Access:
OCSP - URI:http://ocsp2.globalsign.com/rootr3
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.globalsign.com/root-r3.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://www.globalsign.com/repository/
Signature Algorithm: sha256WithRSAEncryption
99:90:c8:2d:5f:42:8a:d4:0b:66:db:98:03:73:11:d4:88:86:
52:28:53:8a:fb:ad:df:fd:73:8e:3a:67:04:db:c3:53:14:70:
14:09:7c:c3:e0:f8:d7:1c:98:1a:a2:c4:3e:db:e9:00:e3:ca:
70:b2:f1:22:30:21:56:db:d3:ad:79:5e:81:58:0b:6d:14:80:
35:f5:6f:5d:1d:eb:9a:47:05:ff:59:8d:00:b1:40:da:90:98:
96:1a:ba:6c:6d:7f:8c:f5:b3:80:df:8c:64:73:36:96:79:79:
69:74:ea:bf:f8:9e:01:8f:a0:95:69:8d:e9:84:ba:e9:e5:d4:
88:38:db:78:3b:98:d0:36:7b:29:b0:d2:52:18:90:de:52:43:
00:ae:6a:27:c8:14:9e:86:95:ac:e1:80:31:30:7e:9a:25:bb:
8b:ac:04:23:a6:99:00:e8:f1:d2:26:ec:0f:7e:3b:8a:2b:92:
38:13:1d:8f:86:cd:86:52:47:e6:34:7c:5b:a4:02:3e:8a:61:
7c:22:76:53:5a:94:53:33:86:b8:92:a8:72:af:a1:f9:52:87:
1f:31:a5:fc:b0:81:57:2f:cd:f4:ce:dc:f6:24:cf:a7:e2:34:
90:68:9d:fe:aa:f1:a9:9a:12:cc:9b:c0:c6:c3:a8:a5:b0:21:
7e:de:48:f6
两张证书完整的结构我们已经有了,现在就是运行Java代码进行抓包了:
- 打开Wireshark抓包工具,在过滤框中输入 ip.host == 116.211.153.233 ,这个ip地址为OCSP验证地址域名对应的ip,OCSP验证地址在上面baidu.crt的证书结构可以看到
- 运行Java代码
- 查看抓包结果
我们找协议列(Protocol)为OCSP的包,目的IP为116.211.153.233的表示OCSP Request,源IP为116.211.153.233的表示OCSP Response,先看请求:
找到包中OCSP部分:
- Request 请求部分
- hashAlgorithm Hash算法
- issuerNameHash 待验证证书签发者名称的Hash值
- issuerKeyHash 待验证证书签发者公钥的Hash值
- serialNumber 待验证证书序列号
然后再看OCSP响应:
响应中包括的内容:
- responseStatus 响应状态
- Response Type 响应类型
- ResponderID 响应者ID
- ProducedAt 响应生成时间
- response 响应列表
- certID 待验证证书ID
- hashAlgorithm Hash算法
- issuerNameHash 待验证证书签发者名称的Hash值
- issuerKeyHash 待验证证书签发者公钥的Hash值
- serialNumber 待验证证书序列号
- certStatus 证书状态(客户端想要的证书状态)状态包括:
- 良好
- 已撤销
- 未知
- thisUpdate 本次证书状态更新时间
- nextUpdate 下次证书状态更新时间,如果在这之前证书被吊销,那么状态不会更新在响应中
- certID 待验证证书ID
- signatureAlgorithm OCSP响应中签名的签名算法
- signature 对响应消息体进行签名后的签名值 OCSP服务器会用私钥对响应进行签名
- certs OCSP服务器证书 具体格式不进行介绍了
客户端获取OCSP响应之后:
- 响应中的certID部分和所请求的证书信息相同
- 使用响应中的证书的公钥对signature进行验签
- 下次更新时间如果存在的话则需要在当前时间之后
先这样吧 有时间再调整