4、证书部署实践:Web服务器证书配置(Nginx/Apache)、客户端证书安装、代码签名证书使用
证书签发下来,只是第一步。真正让证书发挥价值,还得靠正确的部署。我见过太多项目,证书申请流程走得很顺,结果部署时配错了路径、漏了中间链,最后上线还是报不安全。
这一章,咱们就动手实操。把Web服务器、客户端和代码签名这三种场景的部署,一个一个说清楚。
4.1 Web服务器证书配置
Web服务器是证书最常用的场景。Nginx和Apache占了市场大半江山,我重点讲这两个。
4.1.1 准备工作:证书文件与密钥
在配置之前,你得确认手上有这么几个文件:
| 文件 | 常见后缀 | 说明 |
|---|---|---|
| 服务器证书 | .crt / .pem | 由CA签发的服务器公钥证书 |
| 私钥 | .key | 生成CSR时对应的私钥,必须保密 |
| 中间CA证书链 | .ca-bundle / .chain.crt | CA提供的中间证书,用于补齐信任链 |
4.1.2 Nginx 配置实战
Nginx的配置相对简洁。我个人习惯把证书和密钥放在 /etc/nginx/ssl/ 目录下,按域名分文件夹管理。
核心配置段如下:
server {
listen 443 ssl http2;
server_name example.com;
# 证书与密钥路径
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
# 安全配置(推荐)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# 其他站点配置...
location / {
root /var/www/html;
index index.html;
}
}
# HTTP 自动跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
这里有个坑:ssl_certificate 指向的文件,最好是把服务器证书和中间CA证书链拼接在一起的 fullchain.pem。如果你只配了服务器证书,没有配中间链,部分客户端(比如老旧安卓手机)会报错。
cat server.crt intermediate.crt > fullchain.pem顺序不能错——服务器证书在前,中间证书在后。
4.1.3 Apache 配置实战
Apache 的配置稍微啰嗦一点,但逻辑是一样的。我建议用 a2enmod ssl 先确保 SSL 模块已启用。
<VirtualHost *:443>
ServerName example.com
# 证书与密钥路径
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/example.com/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com/privkey.key
SSLCertificateChainFile /etc/apache2/ssl/example.com/intermediate.crt
# 安全配置
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on
# 其他站点配置...
DocumentRoot /var/www/html
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
配置完成后,记得用 apache2ctl configtest 检查语法。嗯,这一步很多人会忘,结果重启服务时才发现配错了。
4.1.4 验证部署是否成功
配置完别急着走。我习惯用下面几个方法验证:
- 浏览器访问:地址栏出现小锁图标,点击查看证书信息是否完整。
- openssl 命令行:
openssl s_client -connect example.com:443 -showcerts,检查证书链是否完整。 - 在线检测工具:比如 SSL Labs 的测试,能给出详细评分和改进建议。
- 证书是否在有效期内
- 证书域名是否与访问域名一致
- 证书链是否完整(没有 missing intermediate)
- 是否支持 TLS 1.2 或 1.3
4.2 客户端证书安装
客户端证书主要用于身份认证,比如企业内部系统、VPN接入、或者API调用。部署方式跟Web服务器不太一样,得装在用户的浏览器或操作系统里。
4.2.1 证书格式转换
CA签发的客户端证书通常是 PEM 格式,但Windows系统需要 PKCS#12(.p12 / .pfx)格式。你需要做一次转换:
openssl pkcs12 -export \
-in client.crt \
-inkey client.key \
-out client.p12 \
-certfile ca-chain.crt
执行时会让你设置导出密码。这个密码要告诉用户,安装时会用到。
4.2.2 浏览器安装步骤
以 Chrome/Edge 为例,安装流程大致如下:
- 打开浏览器设置,搜索「证书」或「安全」。
- 进入「管理证书」或「证书管理器」。
- 选择「个人」标签页,点击「导入」。
- 选择刚才生成的 .p12 文件,输入导出密码。
- 根据提示选择证书存储位置,完成导入。
安装完成后,访问需要客户端认证的网站时,浏览器会弹出选择证书的窗口。用户选对证书才能继续访问。
4.2.3 移动端安装
iOS 和 Android 的安装方式略有不同:
- iOS:通过邮件或 MDM 分发 .p12 文件,点击安装后进入「设置」→「通用」→「VPN与设备管理」完成安装。还需要在「关于本机」→「证书信任设置」中手动启用信任。
- Android:进入「设置」→「安全」→「加密与凭据」→「从存储设备安装」,选择 .p12 文件并输入密码。
你想想看,移动端证书管理其实比桌面端更麻烦,因为用户操作路径不统一。有条件的话,建议用 MDM 统一推送,省去用户手动操作的麻烦。
4.3 代码签名证书使用
代码签名证书的作用,是证明你的代码没有被篡改,并且确实来自你。Windows 的 .exe、.dll,macOS 的 .app,还有 Java 的 .jar,都需要签名。
4.3.1 Windows 代码签名
Windows 下最常用的工具是 signtool,它随 Windows SDK 一起安装。基本用法如下:
signtool sign /fd SHA256 /a /f mycert.pfx /p mypassword /t http://timestamp.digicert.com myapp.exe
参数说明:
/fd SHA256:使用 SHA256 哈希算法,别再用 SHA1 了,已经被弃用。/a:自动选择最佳签名证书。/f:指定证书文件(.pfx 格式)。/p:证书密码。/t:时间戳服务器 URL。加了时间戳,即使证书过期,签名依然有效。
4.3.2 macOS 代码签名
macOS 使用 codesign 工具,签名前需要把证书导入到钥匙串:
# 导入证书
security import mycert.p12 -k ~/Library/Keychains/login.keychain
# 签名应用
codesign --force --verify --verbose --sign "Developer ID Application: Your Name" MyApp.app
# 验证签名
codesign -dv MyApp.app
macOS 的签名比 Windows 严格一些,它还会检查应用内部的资源文件是否完整。如果改了应用里的某个图片,签名就会失效。
4.3.3 代码签名的注意事项
- 私钥保护:代码签名证书的私钥建议存储在硬件令牌(如 YubiKey)或 HSM 中。不要放在构建服务器的磁盘上。
- 自动化构建:在 CI/CD 流水线中签名时,密码不要硬编码在脚本里。用密钥管理服务或环境变量注入。
- 双签名:如果你的软件需要兼容旧版 Windows(比如 Windows 7),可能需要同时签 SHA1 和 SHA256。不过现在 SHA1 签名基本可以淘汰了。
4.4 本章知识体系
下面这张图,把三种证书部署场景的核心流程串起来了。你可以对照着梳理自己的部署步骤。
三种场景虽然差异不小,但核心原则是相通的:证书链要完整、私钥要保护好、部署完要验证。把这些基本功练扎实了,证书部署这块基本不会出大问题。