4. 轻量级证书签发实践:用OpenSSL搭建小型CA
说实话,很多搞边缘计算的朋友一开始都觉得CA这事儿离自己挺远的。直到有一次我在现场调试,发现网关设备之间因为证书过期集体断连,那叫一个狼狈。从那以后,我养成了一个习惯——不管项目大小,先搭一套自己的CA再说。
这一章,我们就来动手做这件事。你会学到:怎么用OpenSSL搭一个能用的CA,怎么给边缘网关签发设备证书,以及证书格式怎么转、怎么存才安全。
4.1 为什么需要自建CA?
你可能会问:直接用公有CA不行吗?行,但有几个现实问题:
- 成本:边缘网关动辄成百上千台,每张证书都去公有CA买,费用吃不消
- 灵活性:设备证书的有效期、扩展字段、密钥用法,自建CA可以完全控制
- 离线场景:很多边缘节点部署在无互联网环境,自建CA是唯一选择
核心原则:自建CA只用于内部设备认证,不对外提供服务。根证书自己保管好,别泄露出去。
4.2 搭建小型CA的完整流程
我习惯把CA分成两级:根CA和中间CA。根CA只用来签发中间CA证书,平时锁在离线机器上。中间CA才用来签发设备证书,可以放在日常运维环境里。
下面这张图能帮你快速理解整个架构:
4.3 第一步:生成根CA
先创建目录结构,我习惯这样组织:
mkdir -p ~/myca/{root,intermediate,devices}
cd ~/myca/root
生成根CA的私钥和自签名证书:
# 生成根CA私钥(4096位,有效期10年)
openssl genrsa -out ca.key 4096
# 生成根CA自签名证书
openssl req -x509 -new -nodes -key ca.key \
-sha256 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyEdge/CN=MyEdge Root CA" \
-out ca.crt
我的习惯:根CA密钥长度至少4096位,有效期设10年。别设太长,也别太短。我曾经见过有人设了20年,结果算法升级后证书没法用了,还得重新签发。
4.4 第二步:生成中间CA
中间CA的私钥可以放在日常运维机器上,但权限要收窄:
cd ~/myca/intermediate
# 生成中间CA私钥(2048位就够了)
openssl genrsa -out intermediate.key 2048
# 生成证书签名请求
openssl req -new -key intermediate.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyEdge/CN=MyEdge Intermediate CA" \
-out intermediate.csr
# 用根CA签发中间CA证书(有效期5年)
openssl x509 -req -in intermediate.csr \
-CA ../root/ca.crt -CAkey ../root/ca.key \
-CAcreateserial -days 1825 -sha256 \
-extensions v3_ca -extfile <(echo "[v3_ca]
basicConstraints=critical,CA:TRUE,pathlen:0
keyUsage=critical,keyCertSign,cRLSign") \
-out intermediate.crt
这里有个关键点:pathlen:0 表示中间CA不能再签发下级CA,只能签发终端实体证书。这是安全边界,别去掉。
4.5 第三步:为边缘网关签发设备证书
设备证书和CA证书不一样,它不能用来签发其他证书。所以扩展字段要严格控制:
cd ~/myca/devices
# 生成设备私钥(边缘网关性能有限,用2048位)
openssl genrsa -out gateway-001.key 2048
# 生成设备证书请求
openssl req -new -key gateway-001.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyEdge/CN=gateway-001" \
-out gateway-001.csr
# 用中间CA签发设备证书(有效期2年)
openssl x509 -req -in gateway-001.csr \
-CA ../intermediate/intermediate.crt \
-CAkey ../intermediate/intermediate.key \
-CAcreateserial -days 730 -sha256 \
-extensions v3_end -extfile <(echo "[v3_end]
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=DNS:gateway-001,DNS:gateway-001.local") \
-out gateway-001.crt
注意:设备证书的 basicConstraints=CA:FALSE 必须写。我曾经在项目里漏掉这个,结果设备证书被拿去签了别的证书,差点造成安全事件。
4.6 证书格式转换:PEM / DER / PFX
不同平台对证书格式要求不一样。Linux设备一般用PEM,Windows用PFX,有些嵌入式系统要DER。转换方法如下:
| 转换方向 | 命令 | 说明 |
|---|---|---|
| PEM → DER | openssl x509 -in cert.pem -outform DER -out cert.der |
证书部分,不含私钥 |
| DER → PEM | openssl x509 -in cert.der -inform DER -out cert.pem |
反向转换 |
| PEM → PFX | openssl pkcs12 -export -in cert.pem -inkey key.pem -out cert.pfx |
需要输入导出密码 |
| PFX → PEM | openssl pkcs12 -in cert.pfx -out cert.pem -nodes |
会同时导出私钥 |
我个人建议:边缘网关内部统一用PEM格式,简单、兼容性好。PFX只在需要导入Windows或Java环境时用。
4.7 证书安全存储
证书和私钥的安全存储,是很多项目容易忽视的环节。我总结了几条硬性要求:
- 私钥必须加密:生成时加上
-aes256参数,或者用openssl rsa -aes256二次加密 - 权限最小化:私钥文件设为600,证书文件设为644
- 硬件安全模块:条件允许的话,把根CA私钥放到HSM或加密U盘里
- 备份策略:根CA私钥至少做3份离线备份,放在不同物理位置
# 加密私钥示例
openssl rsa -aes256 -in gateway-001.key -out gateway-001.enc.key
# 设置文件权限
chmod 600 gateway-001.enc.key
chmod 644 gateway-001.crt
避坑指南:我曾经见过一个项目,把根CA私钥直接放在Git仓库里,还忘了加.gitignore。结果代码泄露,整个CA体系都得重建。记住:私钥永远不要进版本控制。
4.8 验证证书链
签发完成后,一定要验证证书链是否完整:
# 验证设备证书是否由中间CA签发
openssl verify -CAfile intermediate.crt gateway-001.crt
# 验证完整信任链
cat intermediate.crt root/ca.crt > chain.crt
openssl verify -CAfile chain.crt gateway-001.crt
如果输出显示 OK,说明证书链没问题。如果报错,多半是中间证书没拼接对,或者扩展字段写错了。
4.9 本章小结
这一章我们走完了从根CA搭建到设备证书签发的完整流程。你学会了:
- 两级CA架构的设计思路
- 用OpenSSL生成根CA和中间CA
- 为边缘网关签发带扩展约束的设备证书
- PEM/DER/PFX三种格式的互相转换
- 私钥加密存储和权限控制