3、OpenSSL工具链:OpenSSL安装与配置、生成自签名CA证书、生成服务器与客户端证书

好,咱们进入实战环节。这一章我带你搞定OpenSSL工具链。说白了,这是整个TLS加密通信的基石。没有它,后面所有的证书、握手、加密都是空谈。

我个人习惯把OpenSSL比作「数字世界的刻章师傅」。你想想看,CA证书就是公章,服务器证书就是公司营业执照,客户端证书就是员工工牌。而OpenSSL,就是那台刻章机。

3.1 OpenSSL的安装与配置

先说说安装。这事儿其实不复杂,但不同平台有点小差异。

3.1.1 Linux平台(以Ubuntu为例)

我建议直接用包管理器安装,省心。

sudo apt-get update
sudo apt-get install openssl libssl-dev

装完之后,验证一下版本:

openssl version

嗯,这里要注意。如果你看到的是1.1.1以上版本,那基本够用。如果是1.0.2这种老古董,我建议你升级一下。为什么?因为老版本不支持TLS 1.3,而DoIP通信中,TLS 1.3能显著减少握手延迟。

3.1.2 Windows平台

Windows下我推荐用Win64 OpenSSL。去官网下载安装包,或者用Chocolatey:

choco install openssl

装完后记得把安装目录加到PATH环境变量里。我在项目中遇到过有人忘了这步,结果命令行里死活找不到openssl命令,折腾了半天。

3.1.3 配置文件准备

OpenSSL的配置文件通常叫openssl.cnf。Linux下一般在/etc/ssl/目录下,Windows下在安装目录的bin文件夹里。

我个人习惯复制一份到工作目录,然后修改。这样不会影响系统配置。

cp /etc/ssl/openssl.cnf ./my_openssl.cnf
小技巧: 配置文件中[req]段下的distinguished_name和req_extensions很重要。生成证书时,很多坑都出在这里。我建议你提前把常用字段写好,比如国家、组织、通用名等。

3.2 生成自签名CA证书

CA证书,说白了就是「根证书」。它是整个信任链的起点。在DoIP测试环境中,我们不需要去正规CA机构花钱买,自己签一个就行。

3.2.1 生成CA私钥

先造一把「私钥」。这把钥匙要藏好,不能给别人。

openssl genrsa -out ca.key 2048

这里用了2048位。为什么不用1024?因为1024现在被认为不够安全。为什么不用4096?因为DoIP场景下,性能也很重要,2048是平衡点。我曾经在项目里试过4096,结果ECU启动时证书加载慢了将近1秒,客户直接投诉了。

3.2.2 生成CA证书

有了私钥,就可以自签CA证书了。

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -config my_openssl.cnf

执行后会让你填一堆信息。这里我重点说几个:

字段 建议值 说明
Common Name (CN) MyDoIP CA CA的名字,随便起
Organization (O) YourCompany 组织名称
Validity 3650天 10年有效期,够用了
注意: 这里的Common Name不要和后面服务器证书的CN重复。我曾经见过有人图省事全填一样的,结果TLS握手时证书链验证失败,查了半天才发现是CN冲突。

3.3 生成服务器证书

服务器证书,就是给DoIP的Server端用的。在车载网络中,Server通常是网关或中央计算单元。

3.3.1 生成服务器私钥

openssl genrsa -out server.key 2048

3.3.2 生成证书签名请求(CSR)

openssl req -new -key server.key -out server.csr -config my_openssl.cnf

这里填信息时,Common Name要填服务器的IP地址或域名。比如你的DoIP Server IP是192.168.1.100,那CN就填192.168.1.100。

为什么?因为TLS握手时,客户端会检查证书里的CN是否和连接的IP一致。不一致就会报错。我在项目中遇到过有人填了localhost,结果部署到实车上怎么都连不上,就是这个原因。

3.3.3 用CA签名服务器证书

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extensions server_cert -extfile my_openssl.cnf

这个命令有点长,我拆开解释一下:

  • -CA ca.crt -CAkey ca.key:指定用哪个CA来签名
  • -CAcreateserial:生成序列号文件,第一次用需要这个
  • -days 365:证书有效期1年。DoIP场景下,我建议别超过2年
  • -extensions server_cert:从配置文件里读取扩展项,比如密钥用途
关键点: 服务器证书必须包含「数字签名」和「密钥加密」这两个密钥用途。否则TLS握手时,客户端会认为这个证书不合法。你可以在配置文件的server_cert段里加上:
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

3.4 生成客户端证书

客户端证书,就是给DoIP的Client端用的。在车载诊断场景中,Client通常是诊断仪或Tester。

3.4.1 生成客户端私钥和CSR

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -config my_openssl.cnf

这里CN可以填个标识符,比如"Tester-001"。

3.4.2 用CA签名客户端证书

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -extensions client_cert -extfile my_openssl.cnf

客户端证书的扩展项和服务器不同:

keyUsage = digitalSignature
extendedKeyUsage = clientAuth

嗯,这里要注意。客户端证书不需要keyEncipherment,只需要digitalSignature就够了。因为TLS握手时,客户端是用私钥签名来证明身份的,不需要加密。

3.5 验证证书链

证书都生成好了,得验证一下能不能用。

openssl verify -CAfile ca.crt server.crt
openssl verify -CAfile ca.crt client.crt

如果输出是"OK",那就没问题。如果报错,多半是证书链没配好,或者扩展项写错了。

避坑指南: 我曾经在项目里遇到一个诡异的问题——证书验证明明OK,但TLS握手就是失败。后来发现是服务器证书的SAN(Subject Alternative Name)没配。DoIP协议要求证书必须包含SAN字段,而且SAN里要填IP地址。所以建议你在配置文件的server_cert段加上:
subjectAltName = IP:192.168.1.100
或者用DNS名:
subjectAltName = DNS:gateway.example.com

3.6 文件清单与安全建议

最后,整理一下我们生成的文件:

文件 用途 安全等级
ca.key CA私钥 绝密,必须离线保存
ca.crt CA证书 公开,分发给所有设备
server.key 服务器私钥 机密,仅Server持有
server.crt 服务器证书 公开
client.key 客户端私钥 机密,仅Client持有
client.crt 客户端证书 公开

记住一句话:私钥永远不要通过网络传输。我在项目里见过有人图方便,用U盘拷私钥,结果U盘丢了,整个PKI体系都得重建。那叫一个惨。

好了,这一章的内容就到这儿。下一章我们聊聊怎么把这些证书配置到DoIP的TLS通信里,真正跑起来。