TLS 证书(也称为 SSL 证书)是用于在客户端和服务器之间建立安全加密通信的基础组件,广泛应用于 HTTPS、API 通信、邮件传输等领域,是现代互联网安全的基础。
比如HTTPS里的S指的就是TLS。
🔐 TLS 证书的本质
TLS 证书本质上是一个 X.509 格式的数字文件,包含以下关键信息:
内容 |
描述 |
公钥(Public Key) |
用于加密数据或验证签名 |
主题(Subject) |
包括证书持有者的身份信息,如域名(CN)、组织名称等 |
颁发者(Issuer) |
签发该证书的 CA(证书颁发机构)信息 |
有效期(Validity) |
证书有效起止时间 |
签名算法(Signature Algorithm) |
使用的加密算法 |
扩展字段(Extensions) |
如 SAN(subjectAltName)、EKU(extendedKeyUsage)等 |
🌐 TLS 证书的作用
- 身份认证(Authentication)
- 客户端可以验证服务器的身份,防止连接到假冒的服务。
- 支持双向认证(mTLS),客户端也可以被服务端验证。
- 数据加密(Encryption)
- 客户端使用服务器的公钥加密数据,只有拥有私钥的服务器才能解密。
- 建立连接后使用对称加密提高效率。
- 完整性保护(Integrity Protection)
- 使用消息摘要机制(如 HMAC)保证数据未被篡改。
- 支持多域名/IP(通过 SAN)
- 可在一个证书中配置多个域名、IP 地址等访问方式。
比如我们浏览器里常用的https协议,就通过TLS的身份认证机制,构建出了一套完整的信任链
体系,以此来保护我们的上网安全,在我们莫名奇妙的进入到一个未经认证的钓鱼网站时,给出警示。

🏗️ TLS证书自定义签发
先生成根证书及key
1 2 3 4 5
| mkdir -p certs
openssl genrsa -aes256 -out ca-key.pem 4096
|
- -aes256 表示使用 AES-256 加密私钥
1 2 3
| openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -out ca.pem -subj "/CN=docker.com/O=MyCompany"
|
- -x509 表示生成自签名证书
- -days 3650 表示证书有效期 10 年
- -subj “/CN=docker-CA” 中CN (Common Name) ,可以标识一些证书的信息、用途等,比如域名等 /O组织,证书所属组织
可选的subj
字段内容
字段缩写 |
全称 |
示例 |
CN |
Common Name |
/CN=example.com |
O |
Organization |
/O=My Company |
OU |
Organizational Unit |
/OU=IT Department |
L |
Locality |
/L=Beijing |
ST |
State or Province |
/ST=Beijing |
C |
Country |
/C=CN |
emailAddress |
Email Address |
/[email protected] |
根据根证书创建服务端证书
1 2 3 4 5 6 7 8 9 10 11
| openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=<服务器IP或域名>" -sha256 -new -key server-key.pem -out server.csr
echo "subjectAltName = IP:<服务器IP>,IP:127.0.0.1" > extfile.cnf echo "extendedKeyUsage = serverAuth" >> extfile.cnf
openssl x509 -req -days 3650 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
|
根据根证书创建客户端证书
1 2 3 4 5
| openssl genrsa -out client-key.pem 4096 openssl req -subj "/CN=client" -new -key client-key.pem -out client.csr echo "extendedKeyUsage = clientAuth" > extfile-client.cnf openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf
|
配置证书权限
1 2
| chmod -v 400 /etc/docker/certs/*key.pem chmod -v 444 /etc/docker/certs/*.pem
|
验证证书
1
| openssl s_client -connect <服务器IP>:<端口> -CAfile ~/.docker/ca.pem -cert ~/.docker/client-cert.pem -key ~/.docker/client-key.pem
|
如果输出以下内容,表名证书有效
1 2 3 4 5
| CONNECTED(00000003) ... SSL handshake has read XXX bytes and written XXX bytes ... Verify return code: 0 (ok)
|
一键创建证书脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #!/bin/bash
YOUR_COMPANY="your company" SERVER_HOST="192.168.1.2" TIMEOUT_DAYS=365 PASSWORD="123456"
mkdir -p certs && cd certs
echo "🔐 正在生成加密的 RSA 私钥..." openssl genrsa -aes256 -passout pass:$PASSWORD -out ca-key.pem 4096 openssl req -new -x509 -days "$TIMEOUT_DAYS" -key ca-key.pem -sha256 -passin pass:$PASSWORD -out ca.pem -subj "/CN=$SERVER_HOST/O=$YOUR_COMPANY"
echo "㊙ 开始创建服务端证书..." openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=$SERVER_HOST" -sha256 -new -key server-key.pem -out server.csr
echo "subjectAltName = IP:$SERVER_HOST,IP:127.0.0.1" > extfile.cnf echo "extendedKeyUsage = serverAuth" >> extfile.cnf
openssl x509 -req -days "$TIMEOUT_DAYS" -in server.csr -CA ca.pem -CAkey ca-key.pem -passin pass:$PASSWORD -CAcreateserial -out server-cert.pem -extfile extfile.cnf echo "㊙ 服务端证书创建完成,保存为 server-cert.pem, server-key.pem"
echo "🔑 开始创建客户端证书..." openssl genrsa -out client-key.pem 4096 openssl req -subj "/CN=client" -new -key client-key.pem -out client.csr echo "extendedKeyUsage = clientAuth" > extfile-client.cnf openssl x509 -req -days "$TIMEOUT_DAYS" -in client.csr -CA ca.pem -CAkey ca-key.pem -passin pass:$PASSWORD -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf echo "🔑 客户端证书创建完成,保存为 client-cert.pem 和 client-key.pem"
read -p "是否删除临时文件 (server.csr, extfile.cnf, client.csr, extfile-client.cnf)? [y/n] " -r answer if [[ $answer =~ ^[Yy]$ ]]; then rm server.csr extfile.cnf client.csr extfile-client.cnf echo "临时文件已删除。" else echo "临时文件保留。" fi
|