Golang + OpenSSL 实现 TLS 安全通信:从私有 CA 到动态证书加载
Golang + OpenSSL 实现 TLS 安全通信:从私有 CA 到动态证书加载
本文完整演示如何在 Windows 系统 上,使用 OpenSSL 搭建私有 CA,为 Gin 框架的 HTTPS API 签发服务端证书,并实现 客户端安全验证 与 服务端证书动态热更新。所有脚本和代码均可直接运行,适合企业内网、B2B 接口、IoT 设备等私有安全通信场景。
一、为什么需要私有 CA?
在企业内网或 B2B 对接中,常常无法使用公网域名和 Let’s Encrypt 证书。此时,搭建一个私有证书颁发机构(Private CA) 是最佳实践:
- ✅ 无需域名,支持 IP 地址通信
- ✅ 客户端只需信任你的根证书(ca.crt.pem)
- ✅ 服务端证书可随时轮换,客户端无感知
- ✅ 避免浏览器/Postman 的"不安全"警告(因使用自定义信任链)
二、环境准备(Windows)
1. 安装 OpenSSL
下载并安装 Win64 OpenSSL v3.x Light,安装后将 C:\Program Files\OpenSSL-Win64\bin 加入系统 PATH。
验证:
openssl version
# 输出:OpenSSL 3.x.x ...
2. 安装 Go
确保已安装 Go 1.19+,并配置好 GOPATH。
三、搭建私有 CA(PowerShell 脚本)
1. 创建项目目录
mkdir MySecureCA
cd MySecureCA
mkdir certs, crl, newcerts, private, csr
2. 创建 openssl.cnf
在 MySecureCA 目录下创建 openssl.cnf:
[ ca ]
default_ca = CA_default[ CA_default ]
dir = .
certs = ./certs
crl_dir = ./crl
new_certs_dir = ./newcerts
database = ./index.txt
serial = ./serial
RANDFILE = ./private/.randprivate_key = ./private/ca.key.pem
certificate = ./certs/ca.crt.pemdefault_days = 375
default_crl_days= 30
default_md = sha256
preserve = no
policy = policy_strict[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
commonName = supplied[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
x509_extensions = v3_ca[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
commonName = Common Name[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ server_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names[ alt_names ]
IP.1 = 127.0.0.1
IP.2 = 192.168.1.100
✅ 修改 [alt_names] 中的 IP 为你实际的服务端地址
3. 初始化 CA
# 初始化数据库
Set-Content -Path index.txt -Value "" -Encoding UTF8
Set-Content -Path serial -Value "1000`n" -Encoding UTF8# 生成 CA 私钥和根证书
openssl genrsa -out private/ca.key.pem 4096
openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 3650 -sha256 -extensions v3_ca -out certs/ca.crt.pem
📌 保存好 certs/ca.crt.pem —— 这是你要分发给所有客户端的信任根
四、签发服务端证书
# 生成服务端私钥
openssl genrsa -out private/server.key.pem 2048# 生成 CSR
openssl req -config openssl.cnf -key private/server.key.pem -new -sha256 -out csr/server.csr.pem# 用 CA 签发证书
openssl ca -batch -config openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in csr/server.csr.pem -out certs/server.crt.pem
五、Gin 服务端:支持动态 TLS 证书加载
1. 初始化 Go 模块
go mod init my-secure-api
go get github.com/gin-gonic/gin
go get github.com/fsnotify/fsnotify
2. tls_loader.go — 动态证书加载器
package mainimport