4. 轻量级证书签发实践:用OpenSSL搭建小型CA

说实话,很多搞边缘计算的朋友一开始都觉得CA这事儿离自己挺远的。直到有一次我在现场调试,发现网关设备之间因为证书过期集体断连,那叫一个狼狈。从那以后,我养成了一个习惯——不管项目大小,先搭一套自己的CA再说。

这一章,我们就来动手做这件事。你会学到:怎么用OpenSSL搭一个能用的CA,怎么给边缘网关签发设备证书,以及证书格式怎么转、怎么存才安全。

4.1 为什么需要自建CA?

你可能会问:直接用公有CA不行吗?行,但有几个现实问题:

  • 成本:边缘网关动辄成百上千台,每张证书都去公有CA买,费用吃不消
  • 灵活性:设备证书的有效期、扩展字段、密钥用法,自建CA可以完全控制
  • 离线场景:很多边缘节点部署在无互联网环境,自建CA是唯一选择

核心原则:自建CA只用于内部设备认证,不对外提供服务。根证书自己保管好,别泄露出去。

4.2 搭建小型CA的完整流程

我习惯把CA分成两级:根CA和中间CA。根CA只用来签发中间CA证书,平时锁在离线机器上。中间CA才用来签发设备证书,可以放在日常运维环境里。

下面这张图能帮你快速理解整个架构:

小型CA证书签发架构 根CA (离线) ca.crt / ca.key 中间CA (在线) intermediate.crt / intermediate.key 设备证书1 gateway-001.crt 设备证书2 gateway-002.crt 设备证书N gateway-NNN.crt 💡 根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三种格式的互相转换
  • 私钥加密存储和权限控制