HTTPS-TLS加密与证书完全指南(下)

HTTPS加密与证书完全指南(下)

1. 证书格式

1.1 PEM格式

复制代码
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIJAJC1HiIAZAiUMA0G...
-----END CERTIFICATE-----
特点 说明
扩展名 .pem, .crt, .cer
编码 Base64 ASCII
可读性 可以用文本编辑器打开
用途 Apache、Nginx、大多数Linux系统

1.2 DER格式

特点 说明
扩展名 .der, .cer
编码 二进制
可读性 无法直接查看
用途 Java、Windows

1.3 PFX/P12格式

特点 说明
扩展名 .pfx, .p12
编码 二进制
包含 证书 + 私钥 + 中间证书
用途 Windows IIS、Java Tomcat

形象类比: 证书格式 = 文件压缩格式

  • PEM = ZIP(通用、可预览内容)
  • DER = RAR(更紧凑、需要专用工具)
  • PFX = 7z打包(把证书+私钥+中间证书全打包)

1.4 格式转换

bash 复制代码
# PEM → DER
openssl x509 -in cert.pem -outform DER -out cert.der

# DER → PEM
openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem

# PEM + 私钥 → PFX
openssl pkcs12 -export -in cert.pem -inkey key.pem -out cert.pfx

2. 调试排错工具

2.1 openssl s_client

bash 复制代码
# 查看证书链与协商出的加密参数
openssl s_client -connect example.com:443

# 打印完整证书链(含中间证书)
openssl s_client -connect example.com:443 -showcerts

# 强制指定 TLS 版本(测试兼容性/降级风险)
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3

# 指定 SNI(访问共享 IP 的虚拟主机时必带)
openssl s_client -connect 1.2.3.4:443 -servername example.com

# 只看证书,不真正建立会话(适合脚本)
echo | openssl s_client -connect example.com:443 2>/dev/null

2.2 openssl verify / x509(离线验证与查看)

⚠️ 注意:openssl s_client -verify N 中的 N 是证书链校验深度,不是"验证几次",

也不能替代 openssl verify 做严格的链验证。验证证书本身建议用下面的命令。

bash 复制代码
# 用 CA 证书验证服务器证书(最常用的离线验证方式)
openssl verify -CAfile ca.crt server.crt

# 证书链包含中间 CA 时,按顺序拼接
openssl verify -CAfile ca.crt -untrusted intermediate.crt server.crt

# 查看证书所有字段(SAN、有效期、指纹、签名算法)
openssl x509 -in server.crt -text -noout

# 单独查看有效期
openssl x509 -in server.crt -noout -dates

# 查看证书指纹(用于证书固定 Pinning)
openssl x509 -in server.crt -noout -fingerprint -sha256

2.3 浏览器开发者工具

浏览器 操作
Chrome F12 → Security → View Certificate
Firefox F12 → Security → View Certificate
Edge F12 → Security → View Certificate

2.4 在线工具

工具 网址 用途
SSL Labs ssllabs.com/ssltest 全面检测证书和配置
Why No Padlock whynopadlock.com 检查混合内容
Certificate Search crt.sh 搜索CT日志中的证书

排错流程:

  1. openssl s_client查看证书链是否完整
  2. 检查证书是否过期
  3. 检查域名是否匹配
  4. 检查浏览器是否信任该CA
  5. 用SSL Labs评分诊断配置问题

3. TLS 1.3实际流程

RTT(Round-Trip Time) 是指数据包从发送到收到确认所需的时间,即一个网络往返的时间。

握手阶段 TLS 1.2 TLS 1.3
完成握手 2-RTT(两次往返) 1-RTT(一次往返)
首字节延迟 需等待握手完成 需等待握手完成
0-RTT恢复 不支持 支持(会话恢复)

TLS 1.3将握手从2-RTT压缩到1-RTT。
服务器 客户端 服务器 客户端 #mermaid-svg-XlM0ipXGHPho2Nbf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XlM0ipXGHPho2Nbf .error-icon{fill:#552222;}#mermaid-svg-XlM0ipXGHPho2Nbf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XlM0ipXGHPho2Nbf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XlM0ipXGHPho2Nbf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XlM0ipXGHPho2Nbf .marker.cross{stroke:#333333;}#mermaid-svg-XlM0ipXGHPho2Nbf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XlM0ipXGHPho2Nbf p{margin:0;}#mermaid-svg-XlM0ipXGHPho2Nbf .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XlM0ipXGHPho2Nbf text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-XlM0ipXGHPho2Nbf .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-XlM0ipXGHPho2Nbf .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-XlM0ipXGHPho2Nbf #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-XlM0ipXGHPho2Nbf .sequenceNumber{fill:white;}#mermaid-svg-XlM0ipXGHPho2Nbf #sequencenumber{fill:#333;}#mermaid-svg-XlM0ipXGHPho2Nbf #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-XlM0ipXGHPho2Nbf .messageText{fill:#333;stroke:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XlM0ipXGHPho2Nbf .labelText,#mermaid-svg-XlM0ipXGHPho2Nbf .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .loopText,#mermaid-svg-XlM0ipXGHPho2Nbf .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-XlM0ipXGHPho2Nbf .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-XlM0ipXGHPho2Nbf .noteText,#mermaid-svg-XlM0ipXGHPho2Nbf .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-XlM0ipXGHPho2Nbf .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XlM0ipXGHPho2Nbf .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XlM0ipXGHPho2Nbf .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XlM0ipXGHPho2Nbf .actorPopupMenu{position:absolute;}#mermaid-svg-XlM0ipXGHPho2Nbf .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-XlM0ipXGHPho2Nbf .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XlM0ipXGHPho2Nbf .actor-man circle,#mermaid-svg-XlM0ipXGHPho2Nbf line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-XlM0ipXGHPho2Nbf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TLS 1.3握手(1-RTT) 加密通信开始 Client Hello + 密钥共享参数 + 支持的版本 Server Hello + 密钥共享参数 + 证书 + Finished Finished HTTP请求(对称加密) HTTP响应(对称加密)

0-RTT恢复:
服务器 客户端 服务器 客户端 #mermaid-svg-8YR6crSR8rw5G51r{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8YR6crSR8rw5G51r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8YR6crSR8rw5G51r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8YR6crSR8rw5G51r .error-icon{fill:#552222;}#mermaid-svg-8YR6crSR8rw5G51r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8YR6crSR8rw5G51r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8YR6crSR8rw5G51r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8YR6crSR8rw5G51r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8YR6crSR8rw5G51r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8YR6crSR8rw5G51r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8YR6crSR8rw5G51r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8YR6crSR8rw5G51r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8YR6crSR8rw5G51r .marker.cross{stroke:#333333;}#mermaid-svg-8YR6crSR8rw5G51r svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8YR6crSR8rw5G51r p{margin:0;}#mermaid-svg-8YR6crSR8rw5G51r .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8YR6crSR8rw5G51r text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-8YR6crSR8rw5G51r .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-8YR6crSR8rw5G51r .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-8YR6crSR8rw5G51r .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-8YR6crSR8rw5G51r .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-8YR6crSR8rw5G51r #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-8YR6crSR8rw5G51r .sequenceNumber{fill:white;}#mermaid-svg-8YR6crSR8rw5G51r #sequencenumber{fill:#333;}#mermaid-svg-8YR6crSR8rw5G51r #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-8YR6crSR8rw5G51r .messageText{fill:#333;stroke:none;}#mermaid-svg-8YR6crSR8rw5G51r .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8YR6crSR8rw5G51r .labelText,#mermaid-svg-8YR6crSR8rw5G51r .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-8YR6crSR8rw5G51r .loopText,#mermaid-svg-8YR6crSR8rw5G51r .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-8YR6crSR8rw5G51r .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-8YR6crSR8rw5G51r .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-8YR6crSR8rw5G51r .noteText,#mermaid-svg-8YR6crSR8rw5G51r .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-8YR6crSR8rw5G51r .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8YR6crSR8rw5G51r .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8YR6crSR8rw5G51r .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8YR6crSR8rw5G51r .actorPopupMenu{position:absolute;}#mermaid-svg-8YR6crSR8rw5G51r .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-8YR6crSR8rw5G51r .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8YR6crSR8rw5G51r .actor-man circle,#mermaid-svg-8YR6crSR8rw5G51r line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-8YR6crSR8rw5G51r :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 使用之前的会话票据 立即开始通信(无需等待握手) Client Hello + 0-RTT数据(用旧密钥加密) Server Hello + 新密钥 + 响应

TLS 1.3改进:

  • 移除RSA密钥交换(强制使用PFS)
  • 移除不安全的加密套件
  • 握手消息加密(防止中间人观察)
  • 支持0-RTT快速恢复

4. SNI(服务器名称指示)

一台服务器多个域名如何工作?
#mermaid-svg-1I9BPu8r87Dy22Rm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1I9BPu8r87Dy22Rm .error-icon{fill:#552222;}#mermaid-svg-1I9BPu8r87Dy22Rm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1I9BPu8r87Dy22Rm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1I9BPu8r87Dy22Rm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1I9BPu8r87Dy22Rm .marker.cross{stroke:#333333;}#mermaid-svg-1I9BPu8r87Dy22Rm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1I9BPu8r87Dy22Rm p{margin:0;}#mermaid-svg-1I9BPu8r87Dy22Rm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster-label text{fill:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster-label span{color:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster-label span p{background-color:transparent;}#mermaid-svg-1I9BPu8r87Dy22Rm .label text,#mermaid-svg-1I9BPu8r87Dy22Rm span{fill:#333;color:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm .node rect,#mermaid-svg-1I9BPu8r87Dy22Rm .node circle,#mermaid-svg-1I9BPu8r87Dy22Rm .node ellipse,#mermaid-svg-1I9BPu8r87Dy22Rm .node polygon,#mermaid-svg-1I9BPu8r87Dy22Rm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1I9BPu8r87Dy22Rm .rough-node .label text,#mermaid-svg-1I9BPu8r87Dy22Rm .node .label text,#mermaid-svg-1I9BPu8r87Dy22Rm .image-shape .label,#mermaid-svg-1I9BPu8r87Dy22Rm .icon-shape .label{text-anchor:middle;}#mermaid-svg-1I9BPu8r87Dy22Rm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1I9BPu8r87Dy22Rm .rough-node .label,#mermaid-svg-1I9BPu8r87Dy22Rm .node .label,#mermaid-svg-1I9BPu8r87Dy22Rm .image-shape .label,#mermaid-svg-1I9BPu8r87Dy22Rm .icon-shape .label{text-align:center;}#mermaid-svg-1I9BPu8r87Dy22Rm .node.clickable{cursor:pointer;}#mermaid-svg-1I9BPu8r87Dy22Rm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1I9BPu8r87Dy22Rm .arrowheadPath{fill:#333333;}#mermaid-svg-1I9BPu8r87Dy22Rm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1I9BPu8r87Dy22Rm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1I9BPu8r87Dy22Rm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1I9BPu8r87Dy22Rm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1I9BPu8r87Dy22Rm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1I9BPu8r87Dy22Rm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster text{fill:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm .cluster span{color:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1I9BPu8r87Dy22Rm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1I9BPu8r87Dy22Rm rect.text{fill:none;stroke-width:0;}#mermaid-svg-1I9BPu8r87Dy22Rm .icon-shape,#mermaid-svg-1I9BPu8r87Dy22Rm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1I9BPu8r87Dy22Rm .icon-shape p,#mermaid-svg-1I9BPu8r87Dy22Rm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1I9BPu8r87Dy22Rm .icon-shape .label rect,#mermaid-svg-1I9BPu8r87Dy22Rm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1I9BPu8r87Dy22Rm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1I9BPu8r87Dy22Rm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1I9BPu8r87Dy22Rm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SNI工作流程
客户端请求https://example.com
在Client Hello中携带域名
服务器根据域名选择证书
返回对应的证书

没有SNI:

  • 服务器不知道客户端要访问哪个域名
  • 无法返回正确的证书

有SNI:

  • 客户端在握手时告诉服务器域名
  • 服务器返回对应域名的证书

形象类比: SNI = 快递柜取件码

快递柜里有很多包裹,你告诉柜子取件码(域名),柜子给你对应的包裹(证书)

5. 性能优化

5.1 TLS终止

#mermaid-svg-cWTqeRouedDQdxra{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cWTqeRouedDQdxra .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cWTqeRouedDQdxra .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cWTqeRouedDQdxra .error-icon{fill:#552222;}#mermaid-svg-cWTqeRouedDQdxra .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cWTqeRouedDQdxra .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cWTqeRouedDQdxra .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cWTqeRouedDQdxra .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cWTqeRouedDQdxra .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cWTqeRouedDQdxra .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cWTqeRouedDQdxra .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cWTqeRouedDQdxra .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cWTqeRouedDQdxra .marker.cross{stroke:#333333;}#mermaid-svg-cWTqeRouedDQdxra svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cWTqeRouedDQdxra p{margin:0;}#mermaid-svg-cWTqeRouedDQdxra .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cWTqeRouedDQdxra .cluster-label text{fill:#333;}#mermaid-svg-cWTqeRouedDQdxra .cluster-label span{color:#333;}#mermaid-svg-cWTqeRouedDQdxra .cluster-label span p{background-color:transparent;}#mermaid-svg-cWTqeRouedDQdxra .label text,#mermaid-svg-cWTqeRouedDQdxra span{fill:#333;color:#333;}#mermaid-svg-cWTqeRouedDQdxra .node rect,#mermaid-svg-cWTqeRouedDQdxra .node circle,#mermaid-svg-cWTqeRouedDQdxra .node ellipse,#mermaid-svg-cWTqeRouedDQdxra .node polygon,#mermaid-svg-cWTqeRouedDQdxra .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cWTqeRouedDQdxra .rough-node .label text,#mermaid-svg-cWTqeRouedDQdxra .node .label text,#mermaid-svg-cWTqeRouedDQdxra .image-shape .label,#mermaid-svg-cWTqeRouedDQdxra .icon-shape .label{text-anchor:middle;}#mermaid-svg-cWTqeRouedDQdxra .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cWTqeRouedDQdxra .rough-node .label,#mermaid-svg-cWTqeRouedDQdxra .node .label,#mermaid-svg-cWTqeRouedDQdxra .image-shape .label,#mermaid-svg-cWTqeRouedDQdxra .icon-shape .label{text-align:center;}#mermaid-svg-cWTqeRouedDQdxra .node.clickable{cursor:pointer;}#mermaid-svg-cWTqeRouedDQdxra .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cWTqeRouedDQdxra .arrowheadPath{fill:#333333;}#mermaid-svg-cWTqeRouedDQdxra .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cWTqeRouedDQdxra .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cWTqeRouedDQdxra .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cWTqeRouedDQdxra .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cWTqeRouedDQdxra .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cWTqeRouedDQdxra .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cWTqeRouedDQdxra .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cWTqeRouedDQdxra .cluster text{fill:#333;}#mermaid-svg-cWTqeRouedDQdxra .cluster span{color:#333;}#mermaid-svg-cWTqeRouedDQdxra div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cWTqeRouedDQdxra .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cWTqeRouedDQdxra rect.text{fill:none;stroke-width:0;}#mermaid-svg-cWTqeRouedDQdxra .icon-shape,#mermaid-svg-cWTqeRouedDQdxra .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cWTqeRouedDQdxra .icon-shape p,#mermaid-svg-cWTqeRouedDQdxra .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cWTqeRouedDQdxra .icon-shape .label rect,#mermaid-svg-cWTqeRouedDQdxra .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cWTqeRouedDQdxra .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cWTqeRouedDQdxra .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cWTqeRouedDQdxra :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TLS
明文
TLS终止
负载均衡器处理TLS握手
后端服务器只处理明文
客户端
负载均衡器
后端服务器

形象类比: TLS终止 = 公司前台收快递

前台签收快递(TLS握手),拆包检查后把内容转交给员工(明文转发)

员工不需要处理快递包装

优点:

  • 后端服务器不需要处理TLS
  • 证书管理集中
  • 负载均衡器可以做SSL卸载

5.2 会话复用

服务器 客户端 服务器 客户端 #mermaid-svg-avYZJ4YYJk3YVXkE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-avYZJ4YYJk3YVXkE .error-icon{fill:#552222;}#mermaid-svg-avYZJ4YYJk3YVXkE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-avYZJ4YYJk3YVXkE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-avYZJ4YYJk3YVXkE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-avYZJ4YYJk3YVXkE .marker.cross{stroke:#333333;}#mermaid-svg-avYZJ4YYJk3YVXkE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-avYZJ4YYJk3YVXkE p{margin:0;}#mermaid-svg-avYZJ4YYJk3YVXkE .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-avYZJ4YYJk3YVXkE text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-avYZJ4YYJk3YVXkE .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-avYZJ4YYJk3YVXkE .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-avYZJ4YYJk3YVXkE #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-avYZJ4YYJk3YVXkE .sequenceNumber{fill:white;}#mermaid-svg-avYZJ4YYJk3YVXkE #sequencenumber{fill:#333;}#mermaid-svg-avYZJ4YYJk3YVXkE #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-avYZJ4YYJk3YVXkE .messageText{fill:#333;stroke:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-avYZJ4YYJk3YVXkE .labelText,#mermaid-svg-avYZJ4YYJk3YVXkE .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .loopText,#mermaid-svg-avYZJ4YYJk3YVXkE .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-avYZJ4YYJk3YVXkE .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-avYZJ4YYJk3YVXkE .noteText,#mermaid-svg-avYZJ4YYJk3YVXkE .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-avYZJ4YYJk3YVXkE .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-avYZJ4YYJk3YVXkE .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-avYZJ4YYJk3YVXkE .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-avYZJ4YYJk3YVXkE .actorPopupMenu{position:absolute;}#mermaid-svg-avYZJ4YYJk3YVXkE .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-avYZJ4YYJk3YVXkE .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-avYZJ4YYJk3YVXkE .actor-man circle,#mermaid-svg-avYZJ4YYJk3YVXkE line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-avYZJ4YYJk3YVXkE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 首次连接 保存会话票据 再次连接(使用会话票据) 跳过完整握手,直接通信 Client Hello Server Hello + 会话票据 Client Hello + 会话票据 直接使用之前的密钥

效果: 握手时间从2-RTT减少到1-RTT

5.3 OCSP装订

📌 概念详见前文 [OCSP Stapling(装订)](#OCSP Stapling(装订)),此处只讲性能影响。

效果: 把客户端的一次额外 OCSP 查询网络往返消除掉,握手直接带上状态信息;既减少延迟,又避免客户端向 OCSP 服务器暴露访问意图(隐私性)。

5.4 0-RTT

服务器 客户端 服务器 客户端 #mermaid-svg-kDOmcuLE6gjbDQwP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kDOmcuLE6gjbDQwP .error-icon{fill:#552222;}#mermaid-svg-kDOmcuLE6gjbDQwP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kDOmcuLE6gjbDQwP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kDOmcuLE6gjbDQwP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kDOmcuLE6gjbDQwP .marker.cross{stroke:#333333;}#mermaid-svg-kDOmcuLE6gjbDQwP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kDOmcuLE6gjbDQwP p{margin:0;}#mermaid-svg-kDOmcuLE6gjbDQwP .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDOmcuLE6gjbDQwP text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kDOmcuLE6gjbDQwP .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kDOmcuLE6gjbDQwP .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kDOmcuLE6gjbDQwP #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kDOmcuLE6gjbDQwP .sequenceNumber{fill:white;}#mermaid-svg-kDOmcuLE6gjbDQwP #sequencenumber{fill:#333;}#mermaid-svg-kDOmcuLE6gjbDQwP #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kDOmcuLE6gjbDQwP .messageText{fill:#333;stroke:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDOmcuLE6gjbDQwP .labelText,#mermaid-svg-kDOmcuLE6gjbDQwP .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .loopText,#mermaid-svg-kDOmcuLE6gjbDQwP .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kDOmcuLE6gjbDQwP .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kDOmcuLE6gjbDQwP .noteText,#mermaid-svg-kDOmcuLE6gjbDQwP .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kDOmcuLE6gjbDQwP .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDOmcuLE6gjbDQwP .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDOmcuLE6gjbDQwP .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kDOmcuLE6gjbDQwP .actorPopupMenu{position:absolute;}#mermaid-svg-kDOmcuLE6gjbDQwP .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kDOmcuLE6gjbDQwP .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kDOmcuLE6gjbDQwP .actor-man circle,#mermaid-svg-kDOmcuLE6gjbDQwP line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kDOmcuLE6gjbDQwP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 无需等待握手完成 Client Hello + 0-RTT数据 响应

效果: 首字节延迟降为0

注意: 0-RTT数据无法防重放攻击,不适合敏感操作


6. 核心概念

概念 一句话解释
HTTPS HTTP + TLS,加密传输
TLS 传输层安全协议,SSL的升级版
非对称加密 公钥加密,私钥解密,用于密钥交换
对称加密 共享密钥,用于数据加密
证书 数字身份证,证明服务器身份
CA 证书颁发机构,信任的起点

7. 进阶概念

概念 一句话解释
证书链 根CA → 中间CA → 服务器证书,层层验证
CRL 证书吊销列表,定期发布作废证书
OCSP 在线证书状态查询,实时检查证书是否有效
OCSP Stapling 服务器代查OCSP,减少客户端请求
CT 证书透明度,公开日志防止CA伪造证书
HSTS 强制浏览器只用HTTPS,防止降级攻击
Certificate Pinning 客户端只信任特定证书,防止中间人攻击
PFS 前向保密,临时密钥交换,历史通信无法解密
SNI 服务器名称指示,一台服务器多域名
TLS终止 负载均衡器处理TLS,后端只处理明文
会话复用 复用之前的密钥,减少握手时间
0-RTT 首字节延迟为0,快速恢复连接

8. 形象类比汇总

概念 类比
HTTP vs HTTPS 明信片 vs 装进保险箱的明信片
非对称加密 保险箱寄钥匙(安全但慢)
对称加密 用钥匙开门锁门(快但需要先拿到钥匙)
CA证书 公安局(发证机关)
服务器证书 身份证(持证用户)
ca.crt 政府公章(盖了这个章的文件就是官方认证的)
ca.key 政府印章本体(丢了谁都能伪造文件)
server.crt 身份证(证明"我是张三,公安局给我发的")
server.key 银行卡密码(丢了钱就没了)
server.csr 办身份证时填的申请表(证办好就没用了)
安装CA证书 小区门禁录入(物业先录入信息,你才能刷脸进门)
SSL vs TLS "拨号上网"这个词(说法沿用,实际早已升级)
证书链 公务员任命体系(县长→省长→国家主席)
CRL 银行挂失名单
OCSP 实时查询银行客服
OCSP Stapling 快递员帮你查包裹状态
CT 公示栏(公安局发的身份证都贴出来)
HSTS 门卫只认VIP卡
Certificate Pinning 公司门禁只认工牌
PFS 用完即焚的密码本
证书格式 文件压缩格式(ZIP/RAR/7z)
SNI 快递柜取件码
TLS终止 公司前台收快递
Let's Encrypt 免费的自动办证机(自助、秒级、自动续期)
Wildcard 证书 一张全家福工牌(只认一级子域名)
SAN 多域名证书 联名工牌(一张证印多个公司)
证书有效期缩短 信用卡有效期变短(强制刷新,降低失窃风险)
mTLS 进出实验室的安全门(双向互相查验工作证)
云手机中转架构 快递中转站(中转只分拣不拆包)

9. 快速诊断清单:HTTPS 报红叉怎么办

遇到浏览器提示"您的连接不是私密连接"或证书异常时,按以下顺序排查:

  1. 查证书是否过期

    bash 复制代码
    openssl x509 -in server.crt -noout -dates
    # 或直接看浏览器证书详情的"有效期"
  2. 查域名是否匹配(看 SAN 而非 CN)

    bash 复制代码
    openssl x509 -in server.crt -text -noout | grep -A1 "Subject Alternative Name"

    浏览器只认 SAN,访问的域名必须在 SAN 列表里。

  3. 查证书链是否完整 (漏发中间证书是最高频问题)

    bash 复制代码
    openssl s_client -connect example.com:443 -showcerts

    如果只看到 1 张证书而不是"服务器证书 + 中间证书",说明 Nginx/Apache 没配 ssl_certificate 的证书链全文件。

  4. 查 CA 是否被信任

    • 公共 CA:确认系统/浏览器没禁用该 CA
    • 自建 CA:确认 ca.crt 已导入客户端"受信任的根证书颁发机构"
  5. 查 TLS 版本与加密套件

    bash 复制代码
    openssl s_client -connect example.com:443 -tls1_2
    openssl s_client -connect example.com:443 -tls1_3

    老客户端连不上常因服务器只开了 TLS 1.3。

💡 快速综合评分 :把域名丢进 SSL Labs 跑一次,A 级以上代表配置健康。


10. 延伸阅读

  • RFC 8446 --- TLS 1.3 官方协议规范
  • RFC 5280 --- X.509 证书标准
  • Mozilla SSL Configuration Generator --- ssl-config.mozilla.org,按服务器软件生成安全配置
  • Let's Encrypt 官方文档 --- letsencrypt.org/docs
  • CA/Browser Forum Baseline Requirements --- CA 行业规则(证书有效期、验证流程)
  • Certificate Transparency --- crt.sh 可公开查询所有签发记录
相关推荐
VidDown2 小时前
视频帧率技术详解:从 24fps 到 120fps,帧率如何影响你的观看体验?
网络·网络协议·编辑器·音视频·视频编解码·视频
Cc_Debugger3 小时前
开发环境使用https配置
javascript·vue.js·https
hbugs0013 小时前
EVE-NG V7常用网络协议流量洞察Filter
网络·网络协议
七夜zippoe4 小时前
DolphinDB WebSocket接入:实时数据流
网络·websocket·网络协议·dolphindb·实时数据流
SomeOtherTime4 小时前
http协议处理播放video/mp4视频
http
勇敢牛牛_5 小时前
Zeplyn:通过P2P构建服务共享网络
网络·网络协议·p2p·服务
开发者联盟league5 小时前
pnpm install报错ERR_SSL_PACKET_LENGTH_TOO_LONG问题解决
网络·网络协议·ssl
森G16 小时前
61、信号与槽机制在 TCP 编程中的应用---------网络编程
网络·c++·qt·网络协议·tcp/ip
llz_11219 小时前
web-第五次课后作业
前端·后端·http