TOC

OCSP 联机证书状态协议

证书使用者拿到证书之后会对其进行完整性校验,可信性校验,有效期校验,适用范围校验。可是其中少了一环:如果证书使用者出于什么原因主动注销证书,如何通知已经在使用该证书的人呢?

PKI (公开密钥基础建设) 有 CRL (Certificate Revocation List 证书撤销列表) 和 OCSP (Online Certificate Status Protocol 联机证书状态协议) 两套机制。

OCSP

RFC 6960:
X.509 Internet Public Key Infrastructure
Online Certificate Status Protocol - OCSP

OCSP 和 CRL 一样都是用于证书状态管理,检查证书是否注销。

  • CRL:使用者通过证书中的 CRL 分发点 (CRL Distribution Point, CDP) 地址获取 CRL 文件,然后通过 CRL 来检查证书是否有效。
    CRL 分发点一般是 CA 维护的,CRL 文件的更新频率一般不够快。
    X509v3 CRL Distribution Points:
      Full Name:
          URI:http://crl3.digicert.com/sha2-ha-server-g6.crl
      Full Name:
          URI:http://crl4.digicert.com/sha2-ha-server-g6.crl
    
    - OCSP:实时检查证书状态 (正常 Good、吊销 Revoked、未知 Unknown) ,是 CRL 的替代品。
    这个地址放在证书的 颁发者信息访问 (Authority Info Access) 拓展字段中。
    Authority Information Access:
      OCSP - URI:http://ocsp.digicert.com
      CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
    

Google Chrome 在 2012 年由于延迟和隐私问题禁用了 OCSP 的默认启用,改用自己的更新机制来同步证书撤销情况。

实验

HOST=www.markjour.com
SERVERNAME=$HOST
PORT=443

# 获取证书
sudo rm -f /tmp/$SERVERNAME.crt && sudo echo -n | openssl s_client -connect $HOST:$PORT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/$SERVERNAME.crt

# 显示证书信息
openssl x509 -noout -text -in /tmp/$SERVERNAME.crt

# openssl s_client -showcerts -connect $HOST:$PORT </dev/null
# echo | openssl s_client -showcerts -connect $HOST:$PORT

# openssl s_client -showcerts -connect $HOST:$PORT </dev/null 2>/dev/null | sed -n "/BEGIN/,/END/p" > /tmp/chain.crt
# gnutls-cli --print-cert $SERVERNAME </dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/chain.crt

# openssl s_client -showcerts -connect $HOST:$PORT </dev/null 2>/dev/null | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM > /tmp/$SERVERNAME.crt
# echo -n | openssl s_client -connect $HOST:$PORT -servername $SERVERNAME | openssl x509 > /tmp/$SERVERNAME.crt
openssl s_client -showcerts -connect $HOST:$PORT </dev/null 2>/dev/null | sed -n "1,/Root/d; /BEGIN/,/END/p" > /tmp/issuer.crt

# sudo apt-get install -y gnutls-bin
# gnutls-cli --print-cert $SERVERNAME </dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $SERVERNAME.crt
# sudo cp $SERVERNAME.crt /usr/local/share/ca-certificates/$SERVERNAME.crt
# sudo update-ca-certificates

# 显示 OCSP URI
openssl x509 -noout -ocsp_uri -in /tmp/$SERVERNAME.crt

# 发出 OCSP 请求
openssl ocsp -issuer /tmp/issuer.crt -cert /tmp/$SERVERNAME.crt -text -url $(openssl x509 -noout -ocsp_uri -in /tmp/$SERVERNAME.crt)