证书

证书是一种用来证明公钥拥有者身份的文件,它通常由一个可信的第三方机构(称为认证机构或CA)签发。证书的作用是让公钥的接收者能够验证公钥的真实性和有效性,从而保证公钥密码体制的安全性。

证书的格式有多种,最常见的是X.509标准,它定义了证书的结构和编码方式。X.509证书有很多扩展格式,如DER、CRT、CER、PEM等,它们在不同的场景中有不同的用途。

X.509标准字段

Version Number:X.509版本号

Serial Number:序列号,用于在CA系统中唯一标识证书

Subject:证书所属的实体,如机器、个人或组织

  • Common Name:受证书影响的域,可接受通配符
  • Country (C):国家
  • Distinguished name (DN):专有名称,例C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net
  • Locality (L):当地
  • Organization (O):组织名称
  • Organizational Unit (OU):组织的部门
  • State or Province (ST, S or P):州或省名称列表

Issuer:颁发者,验证信息并签署证书的实体

  • Common Name (CN):证书颁发机构名称
  • Country (C):证书颁发机构的国家或地区
  • Distinguished name (DN):证书颁发机构的可分辨名称
  • Locality (L):该组织地点
  • Organization (O):组织名称
  • Organizational Unit (OU):组织的部门

Not Before:证书有效的最早时间和日期。通常设置为颁发证书之前的几个小时或几天,以避免时间偏差问题

Not After:证书不再有效的时间和日期

Public Key:公钥,属于证书主体

  • Public Key Algorithm:用于生成公钥的算法
  • Public Key Curve:椭圆曲线公钥算法使用的曲线
  • Public Key Exponent:用于导出公钥的指数
  • Public Key Size:公钥空间的大小
  • Signature Algorithm:用于签署公钥证书的算法
  • Signature:颁发者的私钥对证书主体的签名

x.509v3

  • Key Usage:证书公钥的有效加密用途,常见值包括数字签名验证、密钥加密和证书签名。在 Web 证书中,这将显示为X.509v3 扩展,并且具有以下值Digital Signature
  • Extended Key Usage:可以使用证书的应用程序。常见值包括 TLS 服务器身份验证、电子邮件保护和代码签名
  • Subject Alternative Name:允许用户为单个 SSL证书指定其他主机名
  • Basic Constraint:此扩展描述证书是 CA 证书还是最终实体证书。CA 证书是对其他证书进行签名的证书,而最终实体证书是例如在网页中使用的证书
  • Subject Key Identifier (SKI):此扩展声明证书中公钥的唯一标识符。所有 CA 证书都需要它。CA 将自己的 SKI 传播到已颁发证书上的颁发者密钥标识符(AKI) 扩展。它是主体公钥的哈希值
  • Authority Key Identifier:包含从颁发者证书中的公钥派生的密钥标识符
  • Authority Information Access (AIA):包含有关如何获取此证书的颁发者的信息和OCSP 响应者的地址,可以从中检查此证书的吊销
  • CRL Distribution Points:此扩展标识了可以检查此证书吊销的 CRL 位置。处理证书的应用程序可以从该扩展获取CRL的位置,下载CRL,然后检查该证书的吊销情况
  • CT Precertificate SCTs:有关证书的证书透明度日志

OCSP和CRL

OCSP和CRL都是用来验证证书的有效性的技术,但是它们有一些区别。

CRL(Certificate Revocation List,证书吊销列表)是由CA机构定期发布的一个文件,里面包含了所有被吊销的证书的序列号和吊销原因。浏览器在验证证书的时候,需要下载CRL文件,然后检查证书是否在CRL中,如果在,就说明证书已经失效,不能信任。

OCSP(Online Certificate Status Protocol,在线证书状态协议)是一种实时的验证方式,浏览器在验证证书的时候,不需要下载整个CRL文件,而是向OCSP服务器发送一个请求,包含证书的序列号,OCSP服务器会返回证书的状态,比如good(有效),revoked(吊销),unknown(未知)。

它们两个的主要差异有以下几点:

  1. CRL需要定期更新,如果在更新之间有证书被吊销,浏览器可能无法及时获取最新的信息,而OCSP可以实时反映证书的状态,更及时。
  2. CRL文件可能会很大,下载和处理需要消耗更多的时间和带宽,而OCSP请求和响应都很小,更高效。
  3. CRL只能提供证书的吊销状态,而OCSP可以提供证书的其他状态,比如证书的透明度信息。
  4. CRL需要浏览器自行构建证书链来校验CRL的签名,而OCSP响应包含完整的证书链,无须额外获取。

证书透明度

证书透明度是一种旨在监测和防止证书误发的技术,它要求证书颁发机构(CA)将每个颁发的证书记录到公开的、不可篡改的、只能追加的证书日志中。这样,任何人都可以查询和验证证书的有效性和来源,发现并举报不合法或恶意的证书。证书透明度可以提高证书的可信度和安全性,防止身份伪造和中间人攻击。

证书日志是证书透明度的核心组成部分,它们是一种基于 Merkle 树 的数据结构,可以存储和检索证书的信息。证书日志可以接受任何有效的证书,无论是否过期、吊销或未生效。证书日志只能添加新的证书,不能修改或删除已有的证书。证书日志还可以提供证书的包含性证明,证明证书已经被记录在日志中。证书日志可以由不同的实体运行,例如 CA、浏览器供应商或第三方组织。目前,有多个证书日志可供查询,我们可以使用一些在线工具来查看证书日志的内容,例如 证书签发日志查询crt.sh

证书格式

PEM格式
  • 大多数服务器(例如:Apache)期望证书和私钥位于单独的文件中
  • 通常它们是 Base64 编码的 ASCII 文件
  • PEM 证书使用的扩展名是 .cer、.crt、.pem、.key 文件
  • Apache 和类似文件服务器使用PEM格式的证书
DER 格式
  • DER 格式是证书的二进制形式
  • 所有类型的证书和私钥都可以采用 DER 格式进行编码
  • DER 格式的证书不包含”BEGIN CERTIFICATE/END CERTIFICATE”语句
  • DER 格式的证书最常使用”.cer”和”.der”扩展名
  • DER 通常用于 Java 平台
P7B/PKCS#7 格式
  • PKCS#7 或 P7B 格式以 Base64 ASCII 格式存储,文件扩展名为 .p7b 或 .p7c
  • P7B 文件仅包含证书和链证书(中间 CA),不包含私钥
  • 支持 P7B 文件的最常见平台是 Microsoft Windows 和 Java Tomcat
PFX/P12/PKCS#12 格式
  • PKCS#12 或 PFX/P12 格式是一种二进制格式,用于将服务器证书、中间证书和私钥存储在一个可加密文件中
  • 这些文件通常具有 .pfx 和 .p12 等扩展名
  • 它们通常在 Windows 计算机上用于导入和导出证书和私钥

格式转换

将X.509转换为PEM:

openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem

将PEM转换为DER:

openssl x509 -outform der -in certificatename.pem -out certificatename.der

将DER转换为PEM:

openssl x509 -inform der -in certificatename.der -out certificatename.pem

将PEM转换为P7B:

openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer

将PKCS7转换为PEM:

openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem

将PFX转换为PEM:

openssl pkcs12 -in certificatename.pfx -out certificatename.pem

将PFX转换为PKCS#8:

openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem
openssl pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8

将P7B转换为PFX:

openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer
openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile  cacert.cer