这篇文章试图汇总下证书这块的知识提纲.
证书基本概念
数字签名
- 对内容用Hash函数生成摘要(digest)
- 用私钥对摘要加密,生成数字签名(signature)
- 证书中心(CA)用自己的私钥对某人的公钥和一些相关信息一起加密,生成数字证书(Digital Certificate)
- 用CA的公钥解开数字证书,就可以拿到某人的公钥
数字证书
证书其实就是公钥 + 签名,由第三方认证机构颁发。用来证明某个公钥是谁的,并且内容是正确的。
- 使用最广泛的标准是X.509规范
- 最重要的包括:签发的公开密钥和CA数字签名
- CA数字签名的合法性通过CA证书来证明
认证和鉴权
经常容易混淆的两个概念.
- Authentication/认证: 验证你是你所说的人,确认对方身份. 通常用于访问控制
- Authorization/鉴权: 验证你被许可你正在试图做的事. 用于用户识别访问权限
C/S证书
- 客户端证书: 通常用户客户端/用户身份识别.
- 服务端证书:通常用于加解密内容.
区分客户端/服务端证书可以通过查看"Enhanced Key Usage"字段.
PKI体系
如何管理和分发证书,将用户的个人身份跟公开密钥连接在一起。
常用的实现标准:PKCS和X.509。
流程要点:
- CA生成私钥和签名证书
- 客户端生成公私钥对,把注册信息和公钥发送给CA
- CA为客户端生成证书
- CA负责证书延期(renewal)和撤销(revocation)
主要组件
CA
数字证书认证机构:负责证书的颁发和吊销。
CA含权威的第三方公开证书认证机构和内部认证机构(Enterprise CA).
Root CA/根证书机构
权威的根证书机构, 与中间证书机构的区别:
- Issued to 和Issued by是同一机构.
- Certification Path位于顶级
本身是自签证书.
Intermediate CA/中间证书机构(可选部分)
作为PKI体系的一部分,使证书结构可扩展, Root CA 把任务代理给Intermediate CA。
形成证书信任链,它的证书由parent CA生成.
自签证书
顾名思义, Issued to 和Issued by 是同一机构/人,通常用户非生产环境。
浏览器会显示警告为不可信任, 因为不被公共的根证书机构认可。
RA
对用户身份进行验证(确保公开密钥和个人身份链接,可以防抵赖),校验数据合法性,负责登记,审核通过发给CA
证书数据库
存放用户识别信息和证书,通常采用LDAP目录服务(树状层级)或关系数据库。
生成用户证书的两种方式
- CA生成证书和私钥
- 自己生成公私钥,由CA对公钥进行签发
证书签发请求/CSR
P10是最常用的格式(PKCS#10),一般是一个base64文件,生成公私钥对后,私钥单独存放,将公钥放入P10。
CA收到请求后根据P10信息生成一个没有私钥的公钥证书。
CSR文件生成步骤如下:
- 根据Version、Distinguished Name、Public Key、Attributes生成请求证书;
- 用Private Key加密证书请求信息;
- 根据请求信息、签名算法和签名生成CSR文件;
证书应用
通常用于认证/隐私/加密/数字签名.
常见证书公钥类型:
- RSA
- EC/ECDSA
- DSA/EdDSA
- SM2
常见数字证书类型
- Certificate Signing Request (.csr)
- Base64编码的X.509证书 (.cer/.crt) (用于导出)
- Privacy-enhanced Electronic Mail (.pem) (Base64编码改进版,OpenSSL所使用)
- DER编码的二进制X.509证书(.cer/.der/.crt)
- 加密消息语法标准 (PKCS#7) 证书 (.p7b/.p7r/.spc)
- 个人信息交换格式 (PKCS#12) 证书 (.pfx/.p12)/ Java Keystore (JKS)
PKCS#12 证书用于客户端, 是唯一可以被导出证书和私钥的文件格式.
.pem格式可以在一个文件包含下面一种或全部的信息:
- Issued Public Certificate (Client/Server)
- Intermediate CA Certificate
- Root CA certificate
- Private Key(.key) (Linux or Java)
- Certificate Revocation List (.crl extension) (CRL Distribution Points)
- Certificate Trust List (.stl)
# 转换pem格式到crt格式
openssl x509 -outform der -in ca.pem -out ca.crt
CA实践
step-ca
- 延长证书过期时间:参考官方配置
- Basic Certificate Authority Operations
生成证书和私钥
注:step-ca颁发的证书默认24小时后失效,可通过配置文件延长
# 前提先安装step和step-ca
step ca init
step-ca $(step path)/config/ca.json
step ca bootstrap --ca-url https://192.168.0.9 --fingerprint 27a0ca7d342e9
# 生成证书和私钥
step ca certificate "localhost" server.crt server.key
# 基本验证
step certificate inspect server.crt --short
# 复制一份CA根证书用户各方互信
step ca root ca.crt
# renew
step ca renew --force server.crt server.key
# 修改/延长默认24h的过期时间
# 编辑 $(step path)/config/ca.json 增加
"authority": {
"claims": {
"maxTLSCertDuration": "8760h",
"defaultTLSCertDuration": "8760h"
}
}
# 使用CSR方式生成证书
step certificate create --csr foo.example.com foo.csr foo.key
step ca sign foo.csr foo.crt
# 查询 fingerprint
step certificate fingerprint $(step path)/certs/root_ca.crt
# 安装CA到信任系统
$ step certificate install $(step path)/certs/root_ca.crt
# 简化输入密码
echo "p4ssword" > password.txt
# 客户端证书用于双向认证 mTLS
step ca certificate "user1" client.crt client.key
Root CA
# 保存Root CA
step ca root root.crt
# 指定证书
curl --cacert root.crt https://localhost:9443/hi
部署实践
生产环境通常部署两套CA:
- Organization CA: 组织身份认证
- TLS CA: 通讯加密
术语/名词缩写
缩写 | 全名 | 注释 |
---|---|---|
PKI | Public Key Infrastructure | 公钥基础设施 |
CA | Certificate Authority | 数字证书认证机构 |
RA | Registration Authority | 注册管理中心 |
OCSP | 证书状态查询系统 | |
CRL | Certificate Revocation List | 证书吊销列表 |
MSPs | Membership Service Providers | |
SSL | Secure Socket Layer | client和server加密通讯协议 |
TLS | Transport Layer Security | SSL继承者,应用层协议 |
CSR | Certificate Signing Request | PKCS#10请求 |
DER | Distinguished Encoding Rules | |
PKCS | Public Key Cryptography Standard | |
LDAP | Lightweight Directory Access Protocol | 轻量目录访问协议, 最常见的证书格式X.509的前身X.500是用于LDAP的前置处理器的目录略图 |
LDIF | LDAP Data Interchange Format | |
JNDI | Java Naming and Directory Interface | Java目录服务接口 |
X.509 | 最常用的数字证书格式,保护一对公私钥,用于加密和认证 | |
MAC | Message Authentication Code |
证书实战调试
import GMail smtp server certificate into your truststore
openssl
s_client -connect smtp.gmail.com:465
# Save output between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" (including that prefix/suffix) into file "gmail.cert"
keytool -import -alias smtp.gmail.com -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file gmail.cert
# Restart your java app