一、背景
公司有个项目,要求政务端和银行端请求需要使用https请求。
二、预备知识
1. HTTPS
HTTPS(HyperText Transfer Protocol Secure)是 HTTP 的安全版本,在 HTTP 基础上通过 SSL/TLS 协议 对通信进行加密,确保数据在客户端与服务器之间传输时的机密性、完整性和身份认证。
简单来讲就是网站中嵌入证书,用户通过浏览器和网站服务器交互时数据会被加密,保证安全。
2. HTTP 与 HTTPS 的区别
| 特性 | HTTP | HTTPS |
|---|---|---|
| 协议 | 明文传输 | 加密传输(SSL/TLS) |
| 端口 | 80 | 443 |
| 安全性 | 无加密,易被窃听、篡改 | 防窃听、防篡改、防冒充 |
| 证书 | 不需要 | 需要 CA 签发的数字证书 |
| 性能 | 较快(无加密开销) | 首次连接有额外开销(TLS 握手),后续接近 HTTP |
3. HTTPS 的核心:SSL/TLS
SSL(Secure Sockets Layer)及其继任者 TLS(Transport Layer Security)是 HTTPS 的加密层。主要提供:
- 加密:混合加密机制,保证数据私密性
- 完整性:消息认证码(MAC)防止数据被篡改
- 身份认证:数字证书验证服务器身份,防止中间人攻击
4. 加密过程概述
HTTPS 采用 混合加密:
-
非对称加密(RSA/ECC)
- 用于握手阶段,安全交换对称密钥
- 公钥加密,私钥解密,保证密钥传输安全
-
对称加密(AES/ChaCha20)
- 握手完成后,使用协商出的对称密钥加密实际通信数据
- 速度快,适合大量数据
5. TLS 握手流程(简化版)
- Client Hello:客户端发送支持的 TLS 版本、加密套件、随机数
- Server Hello:服务器选择加密套件,发送服务器随机数及数字证书
- 证书验证:客户端验证证书合法性(颁发机构、域名、有效期、吊销状态等)
- 密钥交换:客户端生成预主密钥,用服务器公钥加密后发送;双方基于随机数计算出对称密钥(会话密钥)
- 握手完成:双方用会话密钥加密一条测试消息,确认加密通道建立
之后进入加密通信阶段。
6. 数字证书的作用
证书由 CA(证书颁发机构) 签发,绑定域名与公钥,并包含:
- 证书持有者信息
- 公钥
- 签发机构签名
客户端通过预置的 CA 根证书验证签名,确保服务器的身份真实可信,防止 DNS 劫持或伪造网站。
7. HTTPS 的优势
- 安全:防止数据被窃听、篡改,保护用户隐私(如密码、支付信息)
- 信任:浏览器显示安全锁标识,提升用户信任度
- SEO 友好:搜索引擎(如 Google)优先收录 HTTPS 站点
- 合规:满足《网络安全法》、GDPR 等法规对数据加密传输的要求
8. 常见误区
- HTTPS 会让网站变慢很多?
现代硬件与优化(如会话复用、TLS 1.3)使性能损耗极小(通常在 1-2% 以内)。 - HTTPS 需要固定 IP?
通过 SNI(Server Name Indication)技术,多个 HTTPS 站点可共享同一 IP。 - 自签名证书等同于 HTTPS?
自签名证书虽然加密,但无法被浏览器信任,会提示不安全,仅适用于测试环境。
9. 证书链与信任锚
树状结构,可能有多层证书办法机构,最顶层的叫根证书机构,持有根证书私钥,可以签发下一级证书,每个机构或者人使用的证书由证书颁发机构颁发,简单来讲就是用颁发机构的私钥,对证书人的个人信息、公钥等诸多信息做数字签名,对外宣称这个证书由他证明。证书可以公开访问以验证持有者身份,由颁发机构背书,证书对应私钥由持有人持有,不对外公开,用于解密他人通过证书中公钥加密的私密消息。
备注:证书依赖于公钥加密体制,公钥密码体系包含公钥、私钥两把密钥,公钥用户加密、验签,私钥用于解密、签名。
证书通过信任链实现逐级验证:
- 根证书:由 CA 自签名,预置在操作系统/浏览器中,是整个信任体系的锚点。
- 中间证书:由根证书签发,用于签发终端实体证书。中间证书隔离了根证书的风险(即使中间证书私钥泄露,只需吊销中间证书,根证书不受影响)。
- 终端实体证书(叶证书):由中间证书签发,实际部署在服务器、客户端或设备上。
验证过程:客户端验证叶证书 → 中间证书 → 根证书,确认所有签名有效且未被吊销,最终信任该证书。
10. 证书生命周期
- 生成密钥对:申请者生成公钥和私钥,私钥妥善保管。
- 提交 CSR:将公钥及身份信息打包成证书签名请求(CSR)提交给 CA。
- 身份验证:CA(或 RA)验证申请者身份(验证等级不同,流程不同)。
- 签发证书:CA 用私钥对证书签名,生成正式证书。
- 部署与使用:将证书安装到服务器或应用中。
- 吊销:若私钥泄露或不再使用,可通过 CRL/OCSP 吊销证书。
- 续期:证书有效期通常为 1-2 年,过期前需重新签发。
11. 证书格式与编码
证书文件有多种编码和封装格式:
| 格式 | 常见扩展名 | 说明 |
|---|---|---|
| PEM | .pem, .crt, .cer, .key |
Base64 编码,以 -----BEGIN CERTIFICATE----- 开头,文本格式,最通用 |
| DER | .der, .cer |
二进制格式,与 PEM 内容等价 |
| PKCS#12 | .pfx, .p12 |
二进制格式,可同时包含证书和私钥,受密码保护,常用于 Windows/IIS |
| JKS | .jks |
Java 专用密钥库,可存储证书和私钥(已被 PKCS#12 取代) |
转换工具 :常用 OpenSSL、keytool 进行格式转换。
12. 应用场景
- SSL/TLS 证书:用于 HTTPS 网站、API 安全、邮件传输加密(SMTPS、IMAPS)
- 代码签名证书:为软件、驱动程序、移动 App 添加数字签名,防止篡改并标识发布者
- 文档签名证书:用于 PDF、Office 文档的数字签名,保证真实性和不可否认性
- 客户端证书:用于双向 TLS(mTLS)认证,如 VPN、金融系统、物联网设备身份验证
- S/MIME 证书:用于邮件加密和数字签名
13. 总结
HTTPS 是当前互联网安全通信的基础标准,所有涉及敏感信息、用户登录、在线交易的网站都应部署。它不仅保护数据安全,也是建立用户信任和符合法规的必要条件。随着 TLS 1.3 的普及和证书自动化管理(如 Let's Encrypt),部署 HTTPS 的门槛已大幅降低。
三、证书生成步骤
主要过程是:根证书 -->服务器证书,这里的服务器证书指的是我上面所提到需要添加https访问的网站服务器。由于两端都要支持HTTPS,所以都要配置服务器证书。
1.根证书
1.1生成根证书私钥
bash
#生成根证书私钥
openssl genrsa -out root.key 2048
1.2生成根证书请求
bash
#生成根证书请求(按照提示信息填写,也可直接回车)
openssl req -new -key root.key -out root.csr
提示信息
bash
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
1.3创建自签发根证书
bash
#用根证书私钥自签生成根证书(没有填写有效期,默认一个月 -days 30)
openssl x509 -req -in root.csr -extensions v3_ca -signkey root.key -out root.crt
这里根证书私钥自签证书的原因是,证书的格式都是一致的,需要有证书颁发签发,因为根证书颁发机构没有上级,所以根证书颁发机构给自己签发证书,因此有需要大家都信任他。
2.服务器证书
生成服务器证书私钥、生成服务器证书请求、使用根证书私钥签发服务器证书。
2.1创建配置文件openssl.cnf
用于生成证书(这里注意此服务器证书的commonName需要设置成nginx配置文件中的server_name,保持一致)
bash
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
#国家代码,一般都是CN(大写)
countryName = CN
countryName_default = CN
#省份
stateOrProvinceName = Shanghai
stateOrProvinceName_default = Shanghai
#城市
localityName = Shanghai
localityName_default = Shanghai
#企业部门
organizationalUnitName = TestHttps
organizationalUnitName_default = TestHttps
#证书的主域名
commonName = 127.0.0.1 #(如果网页访问是ip就写ip,如果是域名就写域名)
commonName_max = 64
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[alt_names]
# 多域名配置(按需,若不需要,此项可以删除)
DNS.1 = dling.com
DNS.2 = *.dling.com
DNS.3 = www.dling.com
DNS.4 = *.dling8.com
IP.1 = 192.168.0.1
2.2生成服务器证书私钥
bash
#生成服务器证书私钥
openssl genrsa -out server.key 2048
2.3生成服务器证书请求
bash
#生成服务器证书请求(按照提示填写信息,也可直接回车)
openssl req -new -key server.key -out server.csr
提示信息
bash
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
创建自签发服务器证书
bash
#生成服务器证书(此处证书有效期配置的是365天,自行修改)
openssl x509 -days 365 -req -in server.csr -extensions v3_req -CAkey root.key -CA root.crt -CAcreateserial -out server.crt -extfile openssl.cnf
3.生成p12/pfx格式证书(按需)
bash
# 密码:123456 自行配置,别名:alias 自行配置
openssl pkcs12 -export -in bank.crt -inkey bank.key -out bank.p12 -name "alias"
penssl pkcs12 -export -in bank.crt -inkey bank.key -out bank.pfx -name "alias"
3.1介绍
PFX 和 P12 本质上是同一种文件格式,没有区别。
它们都遵循 PKCS#12(Public-Key Cryptography Standards #12)标准,用于存储私钥和公钥证书(通常还包含证书链),并受密码保护。两者的区别仅在于:
3.2扩展名不同
- pfx:源于 Microsoft 生态系统(IIS、Windows 服务器)的惯用扩展名,较早被广泛使用
- p12:更符合标准规范的扩展名,在非 Windows 平台(如 Linux、macOS、Java、OpenSSL)中更常见
3.3使用场景的惯用偏好
- PFX:多见于 Windows 环境下的证书导入/导出(IIS、Exchange、Azure 等)
- P12:常见于 OpenSSL、Java KeyStore、macOS 钥匙串、移动端开发(iOS、Android)等跨平台场景
3.4文件内容完全一致
你可以直接将 .pfx 重命名为 .p12,反之亦然,不影响正常使用(前提是文件完整且密码正确)。两者都支持存储:
- 一个或多个证书(含完整证书链)
- 对应的私钥(可设置是否导出私钥)
- 密码加密保护
4.查看证书有效期
bash
#根证书
openssl x509 -enddate -noout -in root.crt
#服务器证书
openssl x509 -enddate -noout -in server.crt
到期时间输出格式如下:
bash
notAfter=Apr 1 06:33:00 2027 GMT
5.最终的文件目录
bash
total 30K
-rw-r--r-- 1 Administrator 197121 534 Apr 1 14:32 openssl.cnf
-rw-r--r-- 1 Administrator 197121 1.2K Apr 1 14:29 root.crt
-rw-r--r-- 1 Administrator 197121 972 Apr 1 14:29 root.csr
-rw-r--r-- 1 Administrator 197121 1.7K Apr 1 14:27 root.key
-rw-r--r-- 1 Administrator 197121 42 Apr 1 14:33 root.srl
-rw-r--r-- 1 Administrator 197121 1.3K Apr 1 14:33 server.crt
-rw-r--r-- 1 Administrator 197121 972 Apr 1 14:30 server.csr
-rw-r--r-- 1 Administrator 197121 1.7K Apr 1 14:30 server.key
-rw-r--r-- 1 Administrator 197121 2.7K Apr 1 14:35 server.p12
四、NGINX配置
1.网络示意图
简化版,实际网络策略要更复杂。

出去时,应用服务器实际还是调用http请求到nginx,由nginx代理成https请求。
进来时,由nginx接收https请求,代理成http请求到应用服务器。
2.政务侧
bash
# 政务侧入口(即银行请求政务),https转为http
server {
listen 10001 ssl;
ssl_certificate /usr/local/nginx/ssl/server.crt;
ssl_certificate_key /usr/local/nginx/ssl/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /gov {
proxy_pass http://ip:port; # 需要代理到实际处理请求的应用地址
}
}
# 政务侧出口(即政务请求银行),http转为https
server {
listen 10002;
location /gov2bank {
proxy_pass https://bank_nginx_ip:20001; # 代理到银行侧的ng服务器
}
}
3.银行侧
bash
# 银行侧入口(即政务请求银行),https转为http
server {
listen 20001 ssl;
ssl_certificate /usr/local/nginx/ssl/server.crt;
ssl_certificate_key /usr/local/nginx/ssl/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /bank {
proxy_pass http://ip:port; # 需要代理到实际处理请求的应用地址
}
}
# 银行侧出口(即银行请求政务),http转为https
server {
listen 20002;
location /bank2gov {
proxy_pass https://gov_nginx_ip:10001; # 代理到政务侧的ng服务器
}
}