一篇讲清楚加密、签名、证书和 SSH 密钥

一篇讲清楚加密、签名、证书和 SSH 密钥

平时听到 AES、RSA、SHA-256、HMAC、ECDSA、Ed25519、HTTPS、CA 证书、SSH key,很容易觉得它们都在"加密"。其实它们解决的问题并不一样。

最好的理解方式不是背算法名,而是先问:它到底在解决什么问题?

  • 想让别人看不懂内容:加密。
  • 想知道内容有没有被改:哈希、MAC、AEAD。
  • 想证明是谁发的:数字签名、证书、公钥认证。
  • 想安全地产生会话密钥:密钥交换、密钥派生。
  • 想让浏览器相信某个公钥属于某个域名:CA 和证书链。

下面按这个思路,把常见名词放到一张地图里。

1. 总览:这些名词分别管什么

#mermaid-svg-57wsagRKDSCHt39V{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-57wsagRKDSCHt39V .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-57wsagRKDSCHt39V .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-57wsagRKDSCHt39V .error-icon{fill:#552222;}#mermaid-svg-57wsagRKDSCHt39V .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-57wsagRKDSCHt39V .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-57wsagRKDSCHt39V .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-57wsagRKDSCHt39V .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-57wsagRKDSCHt39V .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-57wsagRKDSCHt39V .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-57wsagRKDSCHt39V .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-57wsagRKDSCHt39V .marker{fill:#333333;stroke:#333333;}#mermaid-svg-57wsagRKDSCHt39V .marker.cross{stroke:#333333;}#mermaid-svg-57wsagRKDSCHt39V svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-57wsagRKDSCHt39V p{margin:0;}#mermaid-svg-57wsagRKDSCHt39V .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-57wsagRKDSCHt39V .cluster-label text{fill:#333;}#mermaid-svg-57wsagRKDSCHt39V .cluster-label span{color:#333;}#mermaid-svg-57wsagRKDSCHt39V .cluster-label span p{background-color:transparent;}#mermaid-svg-57wsagRKDSCHt39V .label text,#mermaid-svg-57wsagRKDSCHt39V span{fill:#333;color:#333;}#mermaid-svg-57wsagRKDSCHt39V .node rect,#mermaid-svg-57wsagRKDSCHt39V .node circle,#mermaid-svg-57wsagRKDSCHt39V .node ellipse,#mermaid-svg-57wsagRKDSCHt39V .node polygon,#mermaid-svg-57wsagRKDSCHt39V .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-57wsagRKDSCHt39V .rough-node .label text,#mermaid-svg-57wsagRKDSCHt39V .node .label text,#mermaid-svg-57wsagRKDSCHt39V .image-shape .label,#mermaid-svg-57wsagRKDSCHt39V .icon-shape .label{text-anchor:middle;}#mermaid-svg-57wsagRKDSCHt39V .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-57wsagRKDSCHt39V .rough-node .label,#mermaid-svg-57wsagRKDSCHt39V .node .label,#mermaid-svg-57wsagRKDSCHt39V .image-shape .label,#mermaid-svg-57wsagRKDSCHt39V .icon-shape .label{text-align:center;}#mermaid-svg-57wsagRKDSCHt39V .node.clickable{cursor:pointer;}#mermaid-svg-57wsagRKDSCHt39V .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-57wsagRKDSCHt39V .arrowheadPath{fill:#333333;}#mermaid-svg-57wsagRKDSCHt39V .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-57wsagRKDSCHt39V .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-57wsagRKDSCHt39V .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-57wsagRKDSCHt39V .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-57wsagRKDSCHt39V .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-57wsagRKDSCHt39V .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-57wsagRKDSCHt39V .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-57wsagRKDSCHt39V .cluster text{fill:#333;}#mermaid-svg-57wsagRKDSCHt39V .cluster span{color:#333;}#mermaid-svg-57wsagRKDSCHt39V 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-57wsagRKDSCHt39V .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-57wsagRKDSCHt39V rect.text{fill:none;stroke-width:0;}#mermaid-svg-57wsagRKDSCHt39V .icon-shape,#mermaid-svg-57wsagRKDSCHt39V .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-57wsagRKDSCHt39V .icon-shape p,#mermaid-svg-57wsagRKDSCHt39V .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-57wsagRKDSCHt39V .icon-shape .label rect,#mermaid-svg-57wsagRKDSCHt39V .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-57wsagRKDSCHt39V .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-57wsagRKDSCHt39V .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-57wsagRKDSCHt39V :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 密码学工具箱
保密性
完整性
身份认证
对称加密

AES, ChaCha20
非对称加密

RSA-OAEP 等
哈希摘要

SHA-256, SHA-512, SHA-3
消息认证码

HMAC, Poly1305
AEAD

AES-GCM, ChaCha20-Poly1305
数字签名

RSA-PSS, ECDSA, Ed25519
证书体系

X.509, CA, 证书链
SSH 公钥认证

authorized_keys, known_hosts
#mermaid-svg-IYwwXJtlvQLkUP4d{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-IYwwXJtlvQLkUP4d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IYwwXJtlvQLkUP4d .error-icon{fill:#552222;}#mermaid-svg-IYwwXJtlvQLkUP4d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IYwwXJtlvQLkUP4d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IYwwXJtlvQLkUP4d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IYwwXJtlvQLkUP4d .marker.cross{stroke:#333333;}#mermaid-svg-IYwwXJtlvQLkUP4d svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IYwwXJtlvQLkUP4d p{margin:0;}#mermaid-svg-IYwwXJtlvQLkUP4d .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster-label text{fill:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster-label span{color:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster-label span p{background-color:transparent;}#mermaid-svg-IYwwXJtlvQLkUP4d .label text,#mermaid-svg-IYwwXJtlvQLkUP4d span{fill:#333;color:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d .node rect,#mermaid-svg-IYwwXJtlvQLkUP4d .node circle,#mermaid-svg-IYwwXJtlvQLkUP4d .node ellipse,#mermaid-svg-IYwwXJtlvQLkUP4d .node polygon,#mermaid-svg-IYwwXJtlvQLkUP4d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IYwwXJtlvQLkUP4d .rough-node .label text,#mermaid-svg-IYwwXJtlvQLkUP4d .node .label text,#mermaid-svg-IYwwXJtlvQLkUP4d .image-shape .label,#mermaid-svg-IYwwXJtlvQLkUP4d .icon-shape .label{text-anchor:middle;}#mermaid-svg-IYwwXJtlvQLkUP4d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IYwwXJtlvQLkUP4d .rough-node .label,#mermaid-svg-IYwwXJtlvQLkUP4d .node .label,#mermaid-svg-IYwwXJtlvQLkUP4d .image-shape .label,#mermaid-svg-IYwwXJtlvQLkUP4d .icon-shape .label{text-align:center;}#mermaid-svg-IYwwXJtlvQLkUP4d .node.clickable{cursor:pointer;}#mermaid-svg-IYwwXJtlvQLkUP4d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IYwwXJtlvQLkUP4d .arrowheadPath{fill:#333333;}#mermaid-svg-IYwwXJtlvQLkUP4d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IYwwXJtlvQLkUP4d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IYwwXJtlvQLkUP4d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IYwwXJtlvQLkUP4d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IYwwXJtlvQLkUP4d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IYwwXJtlvQLkUP4d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster text{fill:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d .cluster span{color:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d 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-IYwwXJtlvQLkUP4d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IYwwXJtlvQLkUP4d rect.text{fill:none;stroke-width:0;}#mermaid-svg-IYwwXJtlvQLkUP4d .icon-shape,#mermaid-svg-IYwwXJtlvQLkUP4d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IYwwXJtlvQLkUP4d .icon-shape p,#mermaid-svg-IYwwXJtlvQLkUP4d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IYwwXJtlvQLkUP4d .icon-shape .label rect,#mermaid-svg-IYwwXJtlvQLkUP4d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IYwwXJtlvQLkUP4d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IYwwXJtlvQLkUP4d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IYwwXJtlvQLkUP4d :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 密码学工具箱
密钥协商与派生
编码与封装
密钥交换

DH, ECDH, X25519
密钥派生

HKDF, Argon2id, bcrypt
编码

Base64, Hex
文件格式

PEM, DER, PKCS#12, OpenSSH key

类别 解决的问题 常见算法/名词 典型场景
对称加密 用同一把密钥加密和解密 AES、ChaCha20 HTTPS 数据传输、磁盘加密、文件加密
非对称密码体系 公钥和私钥成对使用 RSA、ECC、X25519、Ed25519 TLS 握手、签名、密钥交换、证书
哈希摘要 给数据生成固定长度指纹 SHA-256、SHA-512、SHA-3、BLAKE2/3 文件校验、证书指纹、Git 对象
消息认证码 用共享密钥验证消息完整性和来源 HMAC、Poly1305、CMAC API 签名、Webhook 签名、Cookie 防篡改
数字签名 私钥签名,公钥验证 RSA-PSS、ECDSA、Ed25519 Git 签名、软件包签名、SSH 登录、证书签发
密钥交换 双方协商出共享秘密,但不直接传输密钥 DH、ECDH、X25519 HTTPS/TLS、端到端加密
密钥派生 从密码或共享秘密派生安全密钥 HKDF、PBKDF2、bcrypt、scrypt、Argon2id TLS 会话密钥、密码存储
编码/封装 数据表示格式,本身不提供安全性 Base64、Hex、PEM、DER 证书、密钥文件、JWT、SSH key

2. 加密:解决"别人看不懂"

加密关注的是保密性。没有密钥的人即使拿到密文,也不应该知道明文。

对称加密

对称加密是同一把密钥负责加密和解密。
#mermaid-svg-QV17RShlXYBqg4ih{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-QV17RShlXYBqg4ih .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QV17RShlXYBqg4ih .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QV17RShlXYBqg4ih .error-icon{fill:#552222;}#mermaid-svg-QV17RShlXYBqg4ih .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QV17RShlXYBqg4ih .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QV17RShlXYBqg4ih .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QV17RShlXYBqg4ih .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QV17RShlXYBqg4ih .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QV17RShlXYBqg4ih .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QV17RShlXYBqg4ih .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QV17RShlXYBqg4ih .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QV17RShlXYBqg4ih .marker.cross{stroke:#333333;}#mermaid-svg-QV17RShlXYBqg4ih svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QV17RShlXYBqg4ih p{margin:0;}#mermaid-svg-QV17RShlXYBqg4ih .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QV17RShlXYBqg4ih .cluster-label text{fill:#333;}#mermaid-svg-QV17RShlXYBqg4ih .cluster-label span{color:#333;}#mermaid-svg-QV17RShlXYBqg4ih .cluster-label span p{background-color:transparent;}#mermaid-svg-QV17RShlXYBqg4ih .label text,#mermaid-svg-QV17RShlXYBqg4ih span{fill:#333;color:#333;}#mermaid-svg-QV17RShlXYBqg4ih .node rect,#mermaid-svg-QV17RShlXYBqg4ih .node circle,#mermaid-svg-QV17RShlXYBqg4ih .node ellipse,#mermaid-svg-QV17RShlXYBqg4ih .node polygon,#mermaid-svg-QV17RShlXYBqg4ih .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QV17RShlXYBqg4ih .rough-node .label text,#mermaid-svg-QV17RShlXYBqg4ih .node .label text,#mermaid-svg-QV17RShlXYBqg4ih .image-shape .label,#mermaid-svg-QV17RShlXYBqg4ih .icon-shape .label{text-anchor:middle;}#mermaid-svg-QV17RShlXYBqg4ih .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QV17RShlXYBqg4ih .rough-node .label,#mermaid-svg-QV17RShlXYBqg4ih .node .label,#mermaid-svg-QV17RShlXYBqg4ih .image-shape .label,#mermaid-svg-QV17RShlXYBqg4ih .icon-shape .label{text-align:center;}#mermaid-svg-QV17RShlXYBqg4ih .node.clickable{cursor:pointer;}#mermaid-svg-QV17RShlXYBqg4ih .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QV17RShlXYBqg4ih .arrowheadPath{fill:#333333;}#mermaid-svg-QV17RShlXYBqg4ih .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QV17RShlXYBqg4ih .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QV17RShlXYBqg4ih .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QV17RShlXYBqg4ih .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QV17RShlXYBqg4ih .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QV17RShlXYBqg4ih .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QV17RShlXYBqg4ih .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QV17RShlXYBqg4ih .cluster text{fill:#333;}#mermaid-svg-QV17RShlXYBqg4ih .cluster span{color:#333;}#mermaid-svg-QV17RShlXYBqg4ih 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-QV17RShlXYBqg4ih .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QV17RShlXYBqg4ih rect.text{fill:none;stroke-width:0;}#mermaid-svg-QV17RShlXYBqg4ih .icon-shape,#mermaid-svg-QV17RShlXYBqg4ih .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QV17RShlXYBqg4ih .icon-shape p,#mermaid-svg-QV17RShlXYBqg4ih .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QV17RShlXYBqg4ih .icon-shape .label rect,#mermaid-svg-QV17RShlXYBqg4ih .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QV17RShlXYBqg4ih .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QV17RShlXYBqg4ih .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QV17RShlXYBqg4ih :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 明文
用同一把密钥加密
密文
用同一把密钥解密
明文

常见算法:

算法 状态 说明
AES 推荐 最常见的对称加密标准,常见密钥长度 128/192/256 bit
ChaCha20 推荐 软件实现性能好,移动端和无 AES 硬件加速环境常见
3DES 不推荐新系统 老算法,性能和安全边际都不理想
DES 禁用 密钥太短,已经不安全
RC4 禁用 存在严重缺陷

对称加密适合加密大量数据,因为速度快。HTTPS 真正传输网页内容时,用的也是对称加密算法,而不是一直用 RSA 之类的非对称算法加密所有数据。

分组模式和 AEAD

实际使用时,很少只说"我用了 AES"就够了。AES 更像一个底层加密积木,真正落地时还要回答:

  • 数据比一个分组长怎么办?
  • 每次加密相同内容会不会得到相同密文?
  • 密文被人改了,接收方能不能发现?

这就需要"模式"。

AES 是分组加密算法,每次只处理固定大小的数据块。模式负责把 AES 这个底层算法组织起来,用来加密任意长度的数据。

可以粗略理解成:

text 复制代码
AES:底层加密算法
GCM/CBC/CTR/ECB:使用 AES 的方式
AES-GCM:AES + GCM 模式

实际使用时,优先关注 AEAD 这类方案。

推荐优先使用:

  • AES-GCM
  • ChaCha20-Poly1305

它们都属于 AEAD,也就是 Authenticated Encryption with Associated Data,带认证的加密。

AEAD 通常属于对称加密方案:发送方和接收方使用同一把会话密钥完成加密、解密和完整性验证。它解决的是"拿到密钥后怎么安全传数据",不解决"密钥最初怎么安全给到双方"。在 TLS/HTTPS 里,这把会话密钥通常先通过 ECDHE/X25519 这类密钥交换协商出来。

AEAD 可以理解为"加密 + 防篡改"打包好的方案。它不只是把明文变成密文,还会生成一个认证标签 tag。解密时,如果密文、nonce、附加数据或 tag 任何一个对不上,就会验证失败,不应该输出明文。

AEAD 同时提供:

  • 保密性:别人看不懂密文。
  • 完整性:密文被改过会验证失败。
  • 附加数据认证:一些不加密但需要防篡改的数据也能参与验证。

#mermaid-svg-N0pGBvbwrOP6FZqq{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-N0pGBvbwrOP6FZqq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-N0pGBvbwrOP6FZqq .error-icon{fill:#552222;}#mermaid-svg-N0pGBvbwrOP6FZqq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-N0pGBvbwrOP6FZqq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-N0pGBvbwrOP6FZqq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-N0pGBvbwrOP6FZqq .marker.cross{stroke:#333333;}#mermaid-svg-N0pGBvbwrOP6FZqq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-N0pGBvbwrOP6FZqq p{margin:0;}#mermaid-svg-N0pGBvbwrOP6FZqq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster-label text{fill:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster-label span{color:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster-label span p{background-color:transparent;}#mermaid-svg-N0pGBvbwrOP6FZqq .label text,#mermaid-svg-N0pGBvbwrOP6FZqq span{fill:#333;color:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq .node rect,#mermaid-svg-N0pGBvbwrOP6FZqq .node circle,#mermaid-svg-N0pGBvbwrOP6FZqq .node ellipse,#mermaid-svg-N0pGBvbwrOP6FZqq .node polygon,#mermaid-svg-N0pGBvbwrOP6FZqq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-N0pGBvbwrOP6FZqq .rough-node .label text,#mermaid-svg-N0pGBvbwrOP6FZqq .node .label text,#mermaid-svg-N0pGBvbwrOP6FZqq .image-shape .label,#mermaid-svg-N0pGBvbwrOP6FZqq .icon-shape .label{text-anchor:middle;}#mermaid-svg-N0pGBvbwrOP6FZqq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-N0pGBvbwrOP6FZqq .rough-node .label,#mermaid-svg-N0pGBvbwrOP6FZqq .node .label,#mermaid-svg-N0pGBvbwrOP6FZqq .image-shape .label,#mermaid-svg-N0pGBvbwrOP6FZqq .icon-shape .label{text-align:center;}#mermaid-svg-N0pGBvbwrOP6FZqq .node.clickable{cursor:pointer;}#mermaid-svg-N0pGBvbwrOP6FZqq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-N0pGBvbwrOP6FZqq .arrowheadPath{fill:#333333;}#mermaid-svg-N0pGBvbwrOP6FZqq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-N0pGBvbwrOP6FZqq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-N0pGBvbwrOP6FZqq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-N0pGBvbwrOP6FZqq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-N0pGBvbwrOP6FZqq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-N0pGBvbwrOP6FZqq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster text{fill:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq .cluster span{color:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq 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-N0pGBvbwrOP6FZqq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-N0pGBvbwrOP6FZqq rect.text{fill:none;stroke-width:0;}#mermaid-svg-N0pGBvbwrOP6FZqq .icon-shape,#mermaid-svg-N0pGBvbwrOP6FZqq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-N0pGBvbwrOP6FZqq .icon-shape p,#mermaid-svg-N0pGBvbwrOP6FZqq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-N0pGBvbwrOP6FZqq .icon-shape .label rect,#mermaid-svg-N0pGBvbwrOP6FZqq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-N0pGBvbwrOP6FZqq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-N0pGBvbwrOP6FZqq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-N0pGBvbwrOP6FZqq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 密钥
AEAD 加密
nonce/IV
明文
附加数据

不加密但防篡改
密文
认证标签 tag
AEAD 解密并验证
验证通过才输出明文

谨慎使用:

  • AES-CBC:需要正确处理 IV、padding、MAC,否则容易出问题。
  • AES-CTR:必须保证 nonce/计数器不重复。

不要使用:

  • AES-ECB:相同明文块会得到相同密文块,会泄露数据结构。

3. 哈希:解决"生成指纹"

哈希函数把任意长度的数据变成固定长度摘要。
#mermaid-svg-uUtjU3Q0gtjspF8n{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-uUtjU3Q0gtjspF8n .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uUtjU3Q0gtjspF8n .error-icon{fill:#552222;}#mermaid-svg-uUtjU3Q0gtjspF8n .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uUtjU3Q0gtjspF8n .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uUtjU3Q0gtjspF8n .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uUtjU3Q0gtjspF8n .marker.cross{stroke:#333333;}#mermaid-svg-uUtjU3Q0gtjspF8n svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uUtjU3Q0gtjspF8n p{margin:0;}#mermaid-svg-uUtjU3Q0gtjspF8n .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster-label text{fill:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster-label span{color:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster-label span p{background-color:transparent;}#mermaid-svg-uUtjU3Q0gtjspF8n .label text,#mermaid-svg-uUtjU3Q0gtjspF8n span{fill:#333;color:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n .node rect,#mermaid-svg-uUtjU3Q0gtjspF8n .node circle,#mermaid-svg-uUtjU3Q0gtjspF8n .node ellipse,#mermaid-svg-uUtjU3Q0gtjspF8n .node polygon,#mermaid-svg-uUtjU3Q0gtjspF8n .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-uUtjU3Q0gtjspF8n .rough-node .label text,#mermaid-svg-uUtjU3Q0gtjspF8n .node .label text,#mermaid-svg-uUtjU3Q0gtjspF8n .image-shape .label,#mermaid-svg-uUtjU3Q0gtjspF8n .icon-shape .label{text-anchor:middle;}#mermaid-svg-uUtjU3Q0gtjspF8n .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-uUtjU3Q0gtjspF8n .rough-node .label,#mermaid-svg-uUtjU3Q0gtjspF8n .node .label,#mermaid-svg-uUtjU3Q0gtjspF8n .image-shape .label,#mermaid-svg-uUtjU3Q0gtjspF8n .icon-shape .label{text-align:center;}#mermaid-svg-uUtjU3Q0gtjspF8n .node.clickable{cursor:pointer;}#mermaid-svg-uUtjU3Q0gtjspF8n .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-uUtjU3Q0gtjspF8n .arrowheadPath{fill:#333333;}#mermaid-svg-uUtjU3Q0gtjspF8n .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-uUtjU3Q0gtjspF8n .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-uUtjU3Q0gtjspF8n .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uUtjU3Q0gtjspF8n .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-uUtjU3Q0gtjspF8n .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uUtjU3Q0gtjspF8n .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster text{fill:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n .cluster span{color:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n 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-uUtjU3Q0gtjspF8n .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-uUtjU3Q0gtjspF8n rect.text{fill:none;stroke-width:0;}#mermaid-svg-uUtjU3Q0gtjspF8n .icon-shape,#mermaid-svg-uUtjU3Q0gtjspF8n .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uUtjU3Q0gtjspF8n .icon-shape p,#mermaid-svg-uUtjU3Q0gtjspF8n .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-uUtjU3Q0gtjspF8n .icon-shape .label rect,#mermaid-svg-uUtjU3Q0gtjspF8n .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uUtjU3Q0gtjspF8n .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-uUtjU3Q0gtjspF8n .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-uUtjU3Q0gtjspF8n :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 任意长度输入

文件、字符串、证书
哈希函数
固定长度摘要

例如 SHA-256

好的哈希函数应该具备:

  • 单向性:很难从摘要反推出原文。
  • 抗碰撞:很难找到两个不同输入得到相同摘要。
  • 雪崩效应:输入变一点,输出大变。

常见算法:

算法 建议
SHA-256 通用安全场景的常见默认选择
SHA-512 输出更长,在 64 位平台上性能通常不错
SHA-3 另一套标准化哈希设计
BLAKE2/BLAKE3 现代高性能哈希,很多工程场景很好用
MD5 不适合安全场景,只能用于非安全校验或兼容旧系统
SHA-1 不适合安全签名和证书场景

哈希不是加密,因为它不能解密回原文。说"MD5 加密""SHA256 加密"通常是不严谨的。

4. HMAC:解决"消息来自共享密钥持有方,且没被改"

普通哈希只能说明数据摘要是什么,不能说明"是谁生成的"。HMAC 多了一把共享密钥。
#mermaid-svg-Z8dC7sp9Z0p7XzX3{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-Z8dC7sp9Z0p7XzX3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .error-icon{fill:#552222;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .marker.cross{stroke:#333333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 p{margin:0;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster-label text{fill:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster-label span{color:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster-label span p{background-color:transparent;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .label text,#mermaid-svg-Z8dC7sp9Z0p7XzX3 span{fill:#333;color:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node rect,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node circle,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node ellipse,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node polygon,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .rough-node .label text,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node .label text,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .image-shape .label,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .rough-node .label,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node .label,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .image-shape .label,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .icon-shape .label{text-align:center;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node.clickable{cursor:pointer;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .arrowheadPath{fill:#333333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster text{fill:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .cluster span{color:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 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-Z8dC7sp9Z0p7XzX3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .icon-shape,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .icon-shape p,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .icon-shape .label rect,#mermaid-svg-Z8dC7sp9Z0p7XzX3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Z8dC7sp9Z0p7XzX3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

共享密钥 secret
HMAC-SHA256
消息 message
tag
接收方重新计算 HMAC
是否一致
来自共享密钥持有方

且未被篡改
拒绝

常见用途:

  • API 请求签名。
  • Webhook 签名。
  • Cookie/session 防篡改。
  • 内部服务调用鉴权。

注意:HMAC 不是数字签名。HMAC 的验证方也持有同一把 secret,所以验证方理论上也能伪造同样的 HMAC。它适合"双方共享秘密"的场景,不适合证明"只有某个私钥持有人签过"。

5. 数字签名:解决"谁签的、有没有被改"

数字签名是私钥签名,公钥验证。
#mermaid-svg-wNe561uQoiNz8hB3{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-wNe561uQoiNz8hB3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wNe561uQoiNz8hB3 .error-icon{fill:#552222;}#mermaid-svg-wNe561uQoiNz8hB3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wNe561uQoiNz8hB3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wNe561uQoiNz8hB3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wNe561uQoiNz8hB3 .marker.cross{stroke:#333333;}#mermaid-svg-wNe561uQoiNz8hB3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wNe561uQoiNz8hB3 p{margin:0;}#mermaid-svg-wNe561uQoiNz8hB3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wNe561uQoiNz8hB3 .cluster-label text{fill:#333;}#mermaid-svg-wNe561uQoiNz8hB3 .cluster-label span{color:#333;}#mermaid-svg-wNe561uQoiNz8hB3 .cluster-label span p{background-color:transparent;}#mermaid-svg-wNe561uQoiNz8hB3 .label text,#mermaid-svg-wNe561uQoiNz8hB3 span{fill:#333;color:#333;}#mermaid-svg-wNe561uQoiNz8hB3 .node rect,#mermaid-svg-wNe561uQoiNz8hB3 .node circle,#mermaid-svg-wNe561uQoiNz8hB3 .node ellipse,#mermaid-svg-wNe561uQoiNz8hB3 .node polygon,#mermaid-svg-wNe561uQoiNz8hB3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wNe561uQoiNz8hB3 .rough-node .label text,#mermaid-svg-wNe561uQoiNz8hB3 .node .label text,#mermaid-svg-wNe561uQoiNz8hB3 .image-shape .label,#mermaid-svg-wNe561uQoiNz8hB3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-wNe561uQoiNz8hB3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wNe561uQoiNz8hB3 .rough-node .label,#mermaid-svg-wNe561uQoiNz8hB3 .node .label,#mermaid-svg-wNe561uQoiNz8hB3 .image-shape .label,#mermaid-svg-wNe561uQoiNz8hB3 .icon-shape .label{text-align:center;}#mermaid-svg-wNe561uQoiNz8hB3 .node.clickable{cursor:pointer;}#mermaid-svg-wNe561uQoiNz8hB3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wNe561uQoiNz8hB3 .arrowheadPath{fill:#333333;}#mermaid-svg-wNe561uQoiNz8hB3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wNe561uQoiNz8hB3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wNe561uQoiNz8hB3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wNe561uQoiNz8hB3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wNe561uQoiNz8hB3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wNe561uQoiNz8hB3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wNe561uQoiNz8hB3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wNe561uQoiNz8hB3 .cluster text{fill:#333;}#mermaid-svg-wNe561uQoiNz8hB3 .cluster span{color:#333;}#mermaid-svg-wNe561uQoiNz8hB3 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-wNe561uQoiNz8hB3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wNe561uQoiNz8hB3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-wNe561uQoiNz8hB3 .icon-shape,#mermaid-svg-wNe561uQoiNz8hB3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wNe561uQoiNz8hB3 .icon-shape p,#mermaid-svg-wNe561uQoiNz8hB3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wNe561uQoiNz8hB3 .icon-shape .label rect,#mermaid-svg-wNe561uQoiNz8hB3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wNe561uQoiNz8hB3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wNe561uQoiNz8hB3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wNe561uQoiNz8hB3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过
失败
原文
哈希
用私钥签名
私钥

只由签名者保存
签名值
重新计算哈希
用公钥验证
公钥

可以公开
验证结果
身份和完整性成立
内容被改或签名不匹配

数字签名提供:

  • 身份认证:确实是某个私钥持有人签的。
  • 完整性:内容没有被改。
  • 不可抵赖性:在合适的密钥管理和制度前提下,签名者难以否认。

常见算法:

算法 说明
RSA-PSS 现代 RSA 签名方案,通常优先于老的 RSA PKCS#1 v1.5 签名
ECDSA 椭圆曲线签名,常见曲线如 P-256、secp256k1
Ed25519 EdDSA 的常见实例,现代、快、使用简单,SSH 和很多新系统常用

常见用途:

  • SSH 公钥登录。
  • Git commit/tag 签名。
  • 软件包发布签名。
  • TLS 证书签发和握手认证。
  • JWT 的 RS256、ES256、EdDSA。

一个重要区别:

  • 签名不隐藏内容。
  • 加密才隐藏内容。

6. 非对称算法:别把 RSA、ECDSA、X25519 混成一类

非对称密码体系的核心是公钥和私钥,但不同算法用途不同。

名词 类型 主要用途
RSA 非对称算法族 可用于加密和签名,具体要看填充方案,如 RSA-OAEP、RSA-PSS
ECDSA 椭圆曲线签名 签名,不是加密
Ed25519 EdDSA 签名算法实例 签名,不是加密
ECDH 椭圆曲线密钥交换 协商共享秘密
X25519 基于 Curve25519 的密钥交换 协商共享秘密,不是签名
secp256k1 椭圆曲线 常见于区块链签名场景
P-256 / prime256v1 椭圆曲线 TLS 证书、ECDSA、ECDH 常见

容易混的点:

  • Ed25519 是签名算法。
  • X25519 是密钥交换算法。
  • ECDSA 和 ECDH 都可能使用椭圆曲线,但一个用于签名,一个用于密钥交换。

7. 密钥交换:HTTPS 为什么不直接把密钥发过去

HTTPS/TLS 最终传大量数据时需要对称密钥。问题是:客户端和服务器一开始并没有共同密钥,怎么安全地得到同一把密钥?

这就是密钥交换解决的问题。
服务端 客户端 服务端 客户端 #mermaid-svg-C6aHWNOiyhikOAjU{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-C6aHWNOiyhikOAjU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-C6aHWNOiyhikOAjU .error-icon{fill:#552222;}#mermaid-svg-C6aHWNOiyhikOAjU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-C6aHWNOiyhikOAjU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-C6aHWNOiyhikOAjU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-C6aHWNOiyhikOAjU .marker.cross{stroke:#333333;}#mermaid-svg-C6aHWNOiyhikOAjU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-C6aHWNOiyhikOAjU p{margin:0;}#mermaid-svg-C6aHWNOiyhikOAjU .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-C6aHWNOiyhikOAjU text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-C6aHWNOiyhikOAjU .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-C6aHWNOiyhikOAjU .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-C6aHWNOiyhikOAjU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-C6aHWNOiyhikOAjU .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-C6aHWNOiyhikOAjU #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-C6aHWNOiyhikOAjU .sequenceNumber{fill:white;}#mermaid-svg-C6aHWNOiyhikOAjU #sequencenumber{fill:#333;}#mermaid-svg-C6aHWNOiyhikOAjU #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-C6aHWNOiyhikOAjU .messageText{fill:#333;stroke:none;}#mermaid-svg-C6aHWNOiyhikOAjU .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-C6aHWNOiyhikOAjU .labelText,#mermaid-svg-C6aHWNOiyhikOAjU .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-C6aHWNOiyhikOAjU .loopText,#mermaid-svg-C6aHWNOiyhikOAjU .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-C6aHWNOiyhikOAjU .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-C6aHWNOiyhikOAjU .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-C6aHWNOiyhikOAjU .noteText,#mermaid-svg-C6aHWNOiyhikOAjU .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-C6aHWNOiyhikOAjU .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-C6aHWNOiyhikOAjU .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-C6aHWNOiyhikOAjU .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-C6aHWNOiyhikOAjU .actorPopupMenu{position:absolute;}#mermaid-svg-C6aHWNOiyhikOAjU .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-C6aHWNOiyhikOAjU .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-C6aHWNOiyhikOAjU .actor-man circle,#mermaid-svg-C6aHWNOiyhikOAjU line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-C6aHWNOiyhikOAjU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 双方用 ECDHE/X25519 算出同一个共享秘密 之后用派生出的会话密钥进行 AEAD 加密通信 ClientHello:支持的 TLS 版本、算法、客户端临时公钥 ServerHello:选择算法、服务端临时公钥 Certificate:服务器证书链 CertificateVerify:用证书私钥签名握手 transcript Finished Finished

现代 TLS 通常使用临时密钥交换,例如 ECDHE 或 X25519。临时的意思是每次连接都生成新的密钥交换材料。

好处是前向安全:

即使将来服务器证书私钥泄露,过去抓包保存下来的历史流量也不应该因此被解密。

8. 密钥派生:把共享秘密或密码变成真正可用的密钥

密钥派生函数 KDF 用来把"还不能直接当密钥用"的材料,变成适合具体算法使用的密钥。

HKDF

HKDF 常用于从共享秘密派生多个会话密钥。

TLS 1.3 的密钥调度就基于 HKDF 思路,把握手阶段得到的秘密逐步派生成不同用途的密钥。
#mermaid-svg-xkVtfPesbP4Q8kbA{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-xkVtfPesbP4Q8kbA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xkVtfPesbP4Q8kbA .error-icon{fill:#552222;}#mermaid-svg-xkVtfPesbP4Q8kbA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xkVtfPesbP4Q8kbA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xkVtfPesbP4Q8kbA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xkVtfPesbP4Q8kbA .marker.cross{stroke:#333333;}#mermaid-svg-xkVtfPesbP4Q8kbA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xkVtfPesbP4Q8kbA p{margin:0;}#mermaid-svg-xkVtfPesbP4Q8kbA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster-label text{fill:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster-label span{color:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster-label span p{background-color:transparent;}#mermaid-svg-xkVtfPesbP4Q8kbA .label text,#mermaid-svg-xkVtfPesbP4Q8kbA span{fill:#333;color:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA .node rect,#mermaid-svg-xkVtfPesbP4Q8kbA .node circle,#mermaid-svg-xkVtfPesbP4Q8kbA .node ellipse,#mermaid-svg-xkVtfPesbP4Q8kbA .node polygon,#mermaid-svg-xkVtfPesbP4Q8kbA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xkVtfPesbP4Q8kbA .rough-node .label text,#mermaid-svg-xkVtfPesbP4Q8kbA .node .label text,#mermaid-svg-xkVtfPesbP4Q8kbA .image-shape .label,#mermaid-svg-xkVtfPesbP4Q8kbA .icon-shape .label{text-anchor:middle;}#mermaid-svg-xkVtfPesbP4Q8kbA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xkVtfPesbP4Q8kbA .rough-node .label,#mermaid-svg-xkVtfPesbP4Q8kbA .node .label,#mermaid-svg-xkVtfPesbP4Q8kbA .image-shape .label,#mermaid-svg-xkVtfPesbP4Q8kbA .icon-shape .label{text-align:center;}#mermaid-svg-xkVtfPesbP4Q8kbA .node.clickable{cursor:pointer;}#mermaid-svg-xkVtfPesbP4Q8kbA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xkVtfPesbP4Q8kbA .arrowheadPath{fill:#333333;}#mermaid-svg-xkVtfPesbP4Q8kbA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xkVtfPesbP4Q8kbA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xkVtfPesbP4Q8kbA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xkVtfPesbP4Q8kbA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xkVtfPesbP4Q8kbA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xkVtfPesbP4Q8kbA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster text{fill:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA .cluster span{color:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA 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-xkVtfPesbP4Q8kbA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xkVtfPesbP4Q8kbA rect.text{fill:none;stroke-width:0;}#mermaid-svg-xkVtfPesbP4Q8kbA .icon-shape,#mermaid-svg-xkVtfPesbP4Q8kbA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xkVtfPesbP4Q8kbA .icon-shape p,#mermaid-svg-xkVtfPesbP4Q8kbA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xkVtfPesbP4Q8kbA .icon-shape .label rect,#mermaid-svg-xkVtfPesbP4Q8kbA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xkVtfPesbP4Q8kbA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xkVtfPesbP4Q8kbA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xkVtfPesbP4Q8kbA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ECDHE/X25519 共享秘密
HKDF Extract
握手密钥
客户端写密钥
服务端写密钥
Finished 验证密钥
应用数据密钥

密码存储专用 KDF

用户密码通常熵不高,不能直接哈希后入库。密码存储要使用专门的慢哈希/密码哈希方案。
#mermaid-svg-zEqMKmKNQAssho1R{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-zEqMKmKNQAssho1R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zEqMKmKNQAssho1R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zEqMKmKNQAssho1R .error-icon{fill:#552222;}#mermaid-svg-zEqMKmKNQAssho1R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zEqMKmKNQAssho1R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zEqMKmKNQAssho1R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zEqMKmKNQAssho1R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zEqMKmKNQAssho1R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zEqMKmKNQAssho1R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zEqMKmKNQAssho1R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zEqMKmKNQAssho1R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zEqMKmKNQAssho1R .marker.cross{stroke:#333333;}#mermaid-svg-zEqMKmKNQAssho1R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zEqMKmKNQAssho1R p{margin:0;}#mermaid-svg-zEqMKmKNQAssho1R .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zEqMKmKNQAssho1R .cluster-label text{fill:#333;}#mermaid-svg-zEqMKmKNQAssho1R .cluster-label span{color:#333;}#mermaid-svg-zEqMKmKNQAssho1R .cluster-label span p{background-color:transparent;}#mermaid-svg-zEqMKmKNQAssho1R .label text,#mermaid-svg-zEqMKmKNQAssho1R span{fill:#333;color:#333;}#mermaid-svg-zEqMKmKNQAssho1R .node rect,#mermaid-svg-zEqMKmKNQAssho1R .node circle,#mermaid-svg-zEqMKmKNQAssho1R .node ellipse,#mermaid-svg-zEqMKmKNQAssho1R .node polygon,#mermaid-svg-zEqMKmKNQAssho1R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zEqMKmKNQAssho1R .rough-node .label text,#mermaid-svg-zEqMKmKNQAssho1R .node .label text,#mermaid-svg-zEqMKmKNQAssho1R .image-shape .label,#mermaid-svg-zEqMKmKNQAssho1R .icon-shape .label{text-anchor:middle;}#mermaid-svg-zEqMKmKNQAssho1R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zEqMKmKNQAssho1R .rough-node .label,#mermaid-svg-zEqMKmKNQAssho1R .node .label,#mermaid-svg-zEqMKmKNQAssho1R .image-shape .label,#mermaid-svg-zEqMKmKNQAssho1R .icon-shape .label{text-align:center;}#mermaid-svg-zEqMKmKNQAssho1R .node.clickable{cursor:pointer;}#mermaid-svg-zEqMKmKNQAssho1R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zEqMKmKNQAssho1R .arrowheadPath{fill:#333333;}#mermaid-svg-zEqMKmKNQAssho1R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zEqMKmKNQAssho1R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zEqMKmKNQAssho1R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zEqMKmKNQAssho1R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zEqMKmKNQAssho1R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zEqMKmKNQAssho1R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zEqMKmKNQAssho1R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zEqMKmKNQAssho1R .cluster text{fill:#333;}#mermaid-svg-zEqMKmKNQAssho1R .cluster span{color:#333;}#mermaid-svg-zEqMKmKNQAssho1R 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-zEqMKmKNQAssho1R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zEqMKmKNQAssho1R rect.text{fill:none;stroke-width:0;}#mermaid-svg-zEqMKmKNQAssho1R .icon-shape,#mermaid-svg-zEqMKmKNQAssho1R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zEqMKmKNQAssho1R .icon-shape p,#mermaid-svg-zEqMKmKNQAssho1R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zEqMKmKNQAssho1R .icon-shape .label rect,#mermaid-svg-zEqMKmKNQAssho1R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zEqMKmKNQAssho1R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zEqMKmKNQAssho1R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zEqMKmKNQAssho1R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户密码
Argon2id / bcrypt / scrypt / PBKDF2
随机 salt
成本参数

时间/内存/迭代次数
password hash
数据库

常见选择可以按下面的优先级理解:

  • Argon2id:现代优先选择,兼顾抗 GPU/ASIC 破解和侧信道风险。
  • scrypt:内存硬化,也常见。
  • bcrypt:经典可靠,仍广泛使用。
  • PBKDF2:兼容性好,但需要足够高的迭代成本;在新系统里通常不是首选。

不要这样存密码:

text 复制代码
password -> SHA256 -> 数据库

应该这样理解:

text 复制代码
password + salt + cost -> Argon2id/bcrypt/scrypt/PBKDF2 -> password hash

相关名词:

  • salt:盐,每个密码一份随机值,防止相同密码得到相同结果,也防彩虹表。
  • pepper:额外的全局秘密,通常放在数据库之外。
  • cost/work factor:计算成本参数,用来增加离线暴力破解成本。

9. HTTPS/TLS:证书、签名、密钥交换和对称加密的组合拳

HTTPS = HTTP over TLS。

TLS 主要提供:

  • 加密:旁观者看不到 HTTP 内容。
  • 完整性:传输内容被改会被发现。
  • 身份认证:客户端能确认自己连的是目标网站,而不是中间人。

一个简化心智模型:
#mermaid-svg-Vnih6NsvW9FeWOU0{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-Vnih6NsvW9FeWOU0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Vnih6NsvW9FeWOU0 .error-icon{fill:#552222;}#mermaid-svg-Vnih6NsvW9FeWOU0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Vnih6NsvW9FeWOU0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .marker.cross{stroke:#333333;}#mermaid-svg-Vnih6NsvW9FeWOU0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Vnih6NsvW9FeWOU0 p{margin:0;}#mermaid-svg-Vnih6NsvW9FeWOU0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster-label text{fill:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster-label span{color:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster-label span p{background-color:transparent;}#mermaid-svg-Vnih6NsvW9FeWOU0 .label text,#mermaid-svg-Vnih6NsvW9FeWOU0 span{fill:#333;color:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .node rect,#mermaid-svg-Vnih6NsvW9FeWOU0 .node circle,#mermaid-svg-Vnih6NsvW9FeWOU0 .node ellipse,#mermaid-svg-Vnih6NsvW9FeWOU0 .node polygon,#mermaid-svg-Vnih6NsvW9FeWOU0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .rough-node .label text,#mermaid-svg-Vnih6NsvW9FeWOU0 .node .label text,#mermaid-svg-Vnih6NsvW9FeWOU0 .image-shape .label,#mermaid-svg-Vnih6NsvW9FeWOU0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Vnih6NsvW9FeWOU0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .rough-node .label,#mermaid-svg-Vnih6NsvW9FeWOU0 .node .label,#mermaid-svg-Vnih6NsvW9FeWOU0 .image-shape .label,#mermaid-svg-Vnih6NsvW9FeWOU0 .icon-shape .label{text-align:center;}#mermaid-svg-Vnih6NsvW9FeWOU0 .node.clickable{cursor:pointer;}#mermaid-svg-Vnih6NsvW9FeWOU0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .arrowheadPath{fill:#333333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Vnih6NsvW9FeWOU0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Vnih6NsvW9FeWOU0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Vnih6NsvW9FeWOU0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster text{fill:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 .cluster span{color:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 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-Vnih6NsvW9FeWOU0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Vnih6NsvW9FeWOU0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Vnih6NsvW9FeWOU0 .icon-shape,#mermaid-svg-Vnih6NsvW9FeWOU0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Vnih6NsvW9FeWOU0 .icon-shape p,#mermaid-svg-Vnih6NsvW9FeWOU0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Vnih6NsvW9FeWOU0 .icon-shape .label rect,#mermaid-svg-Vnih6NsvW9FeWOU0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Vnih6NsvW9FeWOU0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Vnih6NsvW9FeWOU0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Vnih6NsvW9FeWOU0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否

浏览器访问 https://example.com
服务器发送证书链
浏览器验证证书链、域名、有效期、用途
验证通过?
浏览器警告或拒绝连接
双方进行 ECDHE/X25519 密钥交换
HKDF 派生会话密钥
用 AES-GCM 或 ChaCha20-Poly1305 传输 HTTP 数据

HTTPS 里的角色:

名词 作用
浏览器/客户端 验证服务器证书,协商会话密钥
服务器 提供证书,证明自己拥有对应私钥
CA 证书颁发机构,负责给域名或组织签发证书
根证书 预置在操作系统或浏览器里的信任锚
中间证书 根 CA 授权出来的下级 CA 证书
服务器证书 把域名和服务器公钥绑定起来

一个常见误解是"HTTPS 用证书加密数据"。更准确地说:

  • 证书主要负责身份认证和公钥绑定。
  • 握手阶段会用证书私钥证明服务器身份。
  • 双方通过密钥交换和密钥派生得到会话密钥。
  • 真正传输 HTTP 内容时,通常使用 AEAD 对称加密算法。

10. CA 证书与证书链:我怎么相信这个公钥属于这个域名

PKI 是 Public Key Infrastructure,公钥基础设施。它解决的问题是:我怎么相信某个公钥真的属于某个主体?

证书可以粗略理解为:

text 复制代码
CA 说:这个域名/组织的公钥是这个。
CA 对这句话做了数字签名。

证书链长这样:
#mermaid-svg-UXbZ6OJgxTuQZPtW{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-UXbZ6OJgxTuQZPtW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UXbZ6OJgxTuQZPtW .error-icon{fill:#552222;}#mermaid-svg-UXbZ6OJgxTuQZPtW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UXbZ6OJgxTuQZPtW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .marker.cross{stroke:#333333;}#mermaid-svg-UXbZ6OJgxTuQZPtW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UXbZ6OJgxTuQZPtW p{margin:0;}#mermaid-svg-UXbZ6OJgxTuQZPtW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster-label text{fill:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster-label span{color:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster-label span p{background-color:transparent;}#mermaid-svg-UXbZ6OJgxTuQZPtW .label text,#mermaid-svg-UXbZ6OJgxTuQZPtW span{fill:#333;color:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .node rect,#mermaid-svg-UXbZ6OJgxTuQZPtW .node circle,#mermaid-svg-UXbZ6OJgxTuQZPtW .node ellipse,#mermaid-svg-UXbZ6OJgxTuQZPtW .node polygon,#mermaid-svg-UXbZ6OJgxTuQZPtW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .rough-node .label text,#mermaid-svg-UXbZ6OJgxTuQZPtW .node .label text,#mermaid-svg-UXbZ6OJgxTuQZPtW .image-shape .label,#mermaid-svg-UXbZ6OJgxTuQZPtW .icon-shape .label{text-anchor:middle;}#mermaid-svg-UXbZ6OJgxTuQZPtW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .rough-node .label,#mermaid-svg-UXbZ6OJgxTuQZPtW .node .label,#mermaid-svg-UXbZ6OJgxTuQZPtW .image-shape .label,#mermaid-svg-UXbZ6OJgxTuQZPtW .icon-shape .label{text-align:center;}#mermaid-svg-UXbZ6OJgxTuQZPtW .node.clickable{cursor:pointer;}#mermaid-svg-UXbZ6OJgxTuQZPtW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .arrowheadPath{fill:#333333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UXbZ6OJgxTuQZPtW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UXbZ6OJgxTuQZPtW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UXbZ6OJgxTuQZPtW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster text{fill:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW .cluster span{color:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW 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-UXbZ6OJgxTuQZPtW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UXbZ6OJgxTuQZPtW rect.text{fill:none;stroke-width:0;}#mermaid-svg-UXbZ6OJgxTuQZPtW .icon-shape,#mermaid-svg-UXbZ6OJgxTuQZPtW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UXbZ6OJgxTuQZPtW .icon-shape p,#mermaid-svg-UXbZ6OJgxTuQZPtW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UXbZ6OJgxTuQZPtW .icon-shape .label rect,#mermaid-svg-UXbZ6OJgxTuQZPtW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UXbZ6OJgxTuQZPtW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UXbZ6OJgxTuQZPtW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UXbZ6OJgxTuQZPtW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务器证书

example.com 的公钥
中间 CA 证书

Intermediate CA
根 CA 证书

Root CA
系统/浏览器信任库
签名验证方向
信任锚在本机

浏览器验证证书时,会检查很多东西:

  • 证书链能否一路验证到本机信任库中的根 CA。
  • 当前时间是否在证书有效期内。
  • 访问的域名是否出现在证书的 SAN 中。
  • 证书用途是否允许作为 TLS 服务器证书。
  • 证书是否被吊销,具体依赖 CRL、OCSP、浏览器策略等机制。
  • 服务器是否真的持有证书公钥对应的私钥。

X.509 证书常见字段:

字段 含义
Subject 证书主体,旧系统里常看 CN
SAN Subject Alternative Name,现代 Web PKI 主要用它匹配域名
Issuer 谁签发的证书
Subject Public Key Info 证书绑定的公钥
Validity 有效期
Key Usage 这把钥匙允许做什么
Extended Key Usage 更具体的用途,如 TLS Web Server Authentication
Signature Algorithm CA 用什么算法给证书签名
Serial Number 证书序列号
Fingerprint 证书摘要指纹,不是证书身份本身

CSR 是什么

CSR 是 Certificate Signing Request,证书签名请求。

申请证书的常见流程:
#mermaid-svg-2vXg2lNMqWTvwQlf{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-2vXg2lNMqWTvwQlf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2vXg2lNMqWTvwQlf .error-icon{fill:#552222;}#mermaid-svg-2vXg2lNMqWTvwQlf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2vXg2lNMqWTvwQlf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2vXg2lNMqWTvwQlf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2vXg2lNMqWTvwQlf .marker.cross{stroke:#333333;}#mermaid-svg-2vXg2lNMqWTvwQlf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2vXg2lNMqWTvwQlf p{margin:0;}#mermaid-svg-2vXg2lNMqWTvwQlf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster-label text{fill:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster-label span{color:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster-label span p{background-color:transparent;}#mermaid-svg-2vXg2lNMqWTvwQlf .label text,#mermaid-svg-2vXg2lNMqWTvwQlf span{fill:#333;color:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf .node rect,#mermaid-svg-2vXg2lNMqWTvwQlf .node circle,#mermaid-svg-2vXg2lNMqWTvwQlf .node ellipse,#mermaid-svg-2vXg2lNMqWTvwQlf .node polygon,#mermaid-svg-2vXg2lNMqWTvwQlf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2vXg2lNMqWTvwQlf .rough-node .label text,#mermaid-svg-2vXg2lNMqWTvwQlf .node .label text,#mermaid-svg-2vXg2lNMqWTvwQlf .image-shape .label,#mermaid-svg-2vXg2lNMqWTvwQlf .icon-shape .label{text-anchor:middle;}#mermaid-svg-2vXg2lNMqWTvwQlf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2vXg2lNMqWTvwQlf .rough-node .label,#mermaid-svg-2vXg2lNMqWTvwQlf .node .label,#mermaid-svg-2vXg2lNMqWTvwQlf .image-shape .label,#mermaid-svg-2vXg2lNMqWTvwQlf .icon-shape .label{text-align:center;}#mermaid-svg-2vXg2lNMqWTvwQlf .node.clickable{cursor:pointer;}#mermaid-svg-2vXg2lNMqWTvwQlf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2vXg2lNMqWTvwQlf .arrowheadPath{fill:#333333;}#mermaid-svg-2vXg2lNMqWTvwQlf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2vXg2lNMqWTvwQlf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2vXg2lNMqWTvwQlf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2vXg2lNMqWTvwQlf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2vXg2lNMqWTvwQlf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2vXg2lNMqWTvwQlf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster text{fill:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf .cluster span{color:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf 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-2vXg2lNMqWTvwQlf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2vXg2lNMqWTvwQlf rect.text{fill:none;stroke-width:0;}#mermaid-svg-2vXg2lNMqWTvwQlf .icon-shape,#mermaid-svg-2vXg2lNMqWTvwQlf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2vXg2lNMqWTvwQlf .icon-shape p,#mermaid-svg-2vXg2lNMqWTvwQlf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2vXg2lNMqWTvwQlf .icon-shape .label rect,#mermaid-svg-2vXg2lNMqWTvwQlf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2vXg2lNMqWTvwQlf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2vXg2lNMqWTvwQlf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2vXg2lNMqWTvwQlf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 生成私钥
从私钥导出公钥
生成 CSR

包含公钥和域名等信息
CA 验证域名或组织
CA 签发证书

CSR 包含公钥和申请信息,不包含私钥。

自签名证书

自签名证书就是自己给自己签发的证书。

特点:

  • 加密通信本身可以正常工作。
  • 默认不被浏览器或系统信任。
  • 适合本地开发、内网测试、私有 CA 场景。

如果把自建根 CA 安装进信任库,那么它签发的证书就可以被该系统信任。

11. SSH 密钥:登录服务器时发生了什么

SSH 里容易混两套 key:

  1. 服务器主机密钥:服务器自己生成,通常放在 /etc/ssh/ssh_host_*。客户端用它确认"我连到的是不是这台服务器"。
  2. 用户登录密钥:用户在客户端生成,例如 ~/.ssh/id_ed25519~/.ssh/id_ed25519.pub。服务器用 authorized_keys 判断"这个用户能不能登录"。

所以 known_hosts 在客户端,记录服务器主机公钥;authorized_keys 在服务器,记录允许登录的用户公钥。两套密钥方向相反:主机密钥让客户端认服务器,用户密钥让服务器认客户端用户。

SSH 公钥登录不是把私钥发给服务器,而是用用户私钥完成一次签名证明。
服务器 客户端 服务器 客户端 #mermaid-svg-os0IUpN39yVpX68b{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-os0IUpN39yVpX68b .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-os0IUpN39yVpX68b .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-os0IUpN39yVpX68b .error-icon{fill:#552222;}#mermaid-svg-os0IUpN39yVpX68b .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-os0IUpN39yVpX68b .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-os0IUpN39yVpX68b .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-os0IUpN39yVpX68b .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-os0IUpN39yVpX68b .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-os0IUpN39yVpX68b .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-os0IUpN39yVpX68b .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-os0IUpN39yVpX68b .marker{fill:#333333;stroke:#333333;}#mermaid-svg-os0IUpN39yVpX68b .marker.cross{stroke:#333333;}#mermaid-svg-os0IUpN39yVpX68b svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-os0IUpN39yVpX68b p{margin:0;}#mermaid-svg-os0IUpN39yVpX68b .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-os0IUpN39yVpX68b text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-os0IUpN39yVpX68b .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-os0IUpN39yVpX68b .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-os0IUpN39yVpX68b .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-os0IUpN39yVpX68b .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-os0IUpN39yVpX68b #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-os0IUpN39yVpX68b .sequenceNumber{fill:white;}#mermaid-svg-os0IUpN39yVpX68b #sequencenumber{fill:#333;}#mermaid-svg-os0IUpN39yVpX68b #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-os0IUpN39yVpX68b .messageText{fill:#333;stroke:none;}#mermaid-svg-os0IUpN39yVpX68b .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-os0IUpN39yVpX68b .labelText,#mermaid-svg-os0IUpN39yVpX68b .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-os0IUpN39yVpX68b .loopText,#mermaid-svg-os0IUpN39yVpX68b .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-os0IUpN39yVpX68b .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-os0IUpN39yVpX68b .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-os0IUpN39yVpX68b .noteText,#mermaid-svg-os0IUpN39yVpX68b .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-os0IUpN39yVpX68b .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-os0IUpN39yVpX68b .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-os0IUpN39yVpX68b .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-os0IUpN39yVpX68b .actorPopupMenu{position:absolute;}#mermaid-svg-os0IUpN39yVpX68b .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-os0IUpN39yVpX68b .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-os0IUpN39yVpX68b .actor-man circle,#mermaid-svg-os0IUpN39yVpX68b line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-os0IUpN39yVpX68b :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 请求登录 user@host 出示服务器主机公钥 检查 known_hosts,确认服务器身份 在 authorized_keys 中查找用户公钥 用用户私钥对当前会话的认证数据签名 返回签名 用用户公钥验证签名 验证通过,允许登录

这里的"当前会话的认证数据"包含和本次 SSH 连接绑定的信息,例如会话标识、用户名、服务名、公钥算法和公钥内容。它起到类似挑战数据的作用:旧连接里的签名不能直接拿到新连接里重放。

第一次连接时看到的 host key fingerprint 是服务器主机公钥的指纹,不是你的 id_ed25519.pub 指纹。确认后,客户端会把服务器主机公钥写入 known_hosts

常见文件:

文件 含义
~/.ssh/id_ed25519 客户端用户私钥,证明"我是这个用户",必须保密
~/.ssh/id_ed25519.pub 客户端用户公钥,通常放到服务器 authorized_keys 或 Git 平台
~/.ssh/authorized_keys 服务器端用户公钥列表,用来认客户端用户
~/.ssh/known_hosts 客户端记录的服务器主机公钥,用来认服务器
~/.ssh/config SSH 客户端配置
/etc/ssh/ssh_host_* 服务器主机密钥,通常安装或首次启动 OpenSSH server 时生成

推荐生成 Ed25519 SSH key:

bash 复制代码
ssh-keygen -t ed25519 -C "your_email@example.com"

查看公钥:

bash 复制代码
cat ~/.ssh/id_ed25519.pub

查看指纹:

bash 复制代码
ssh-keygen -lf ~/.ssh/id_ed25519.pub

SSH 里有两个认证方向

用户登录和服务器识别是两个方向:
#mermaid-svg-kQLDerny1WmXB89O{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-kQLDerny1WmXB89O .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kQLDerny1WmXB89O .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kQLDerny1WmXB89O .error-icon{fill:#552222;}#mermaid-svg-kQLDerny1WmXB89O .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kQLDerny1WmXB89O .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kQLDerny1WmXB89O .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kQLDerny1WmXB89O .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kQLDerny1WmXB89O .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kQLDerny1WmXB89O .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kQLDerny1WmXB89O .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kQLDerny1WmXB89O .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kQLDerny1WmXB89O .marker.cross{stroke:#333333;}#mermaid-svg-kQLDerny1WmXB89O svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kQLDerny1WmXB89O p{margin:0;}#mermaid-svg-kQLDerny1WmXB89O .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kQLDerny1WmXB89O .cluster-label text{fill:#333;}#mermaid-svg-kQLDerny1WmXB89O .cluster-label span{color:#333;}#mermaid-svg-kQLDerny1WmXB89O .cluster-label span p{background-color:transparent;}#mermaid-svg-kQLDerny1WmXB89O .label text,#mermaid-svg-kQLDerny1WmXB89O span{fill:#333;color:#333;}#mermaid-svg-kQLDerny1WmXB89O .node rect,#mermaid-svg-kQLDerny1WmXB89O .node circle,#mermaid-svg-kQLDerny1WmXB89O .node ellipse,#mermaid-svg-kQLDerny1WmXB89O .node polygon,#mermaid-svg-kQLDerny1WmXB89O .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kQLDerny1WmXB89O .rough-node .label text,#mermaid-svg-kQLDerny1WmXB89O .node .label text,#mermaid-svg-kQLDerny1WmXB89O .image-shape .label,#mermaid-svg-kQLDerny1WmXB89O .icon-shape .label{text-anchor:middle;}#mermaid-svg-kQLDerny1WmXB89O .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kQLDerny1WmXB89O .rough-node .label,#mermaid-svg-kQLDerny1WmXB89O .node .label,#mermaid-svg-kQLDerny1WmXB89O .image-shape .label,#mermaid-svg-kQLDerny1WmXB89O .icon-shape .label{text-align:center;}#mermaid-svg-kQLDerny1WmXB89O .node.clickable{cursor:pointer;}#mermaid-svg-kQLDerny1WmXB89O .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kQLDerny1WmXB89O .arrowheadPath{fill:#333333;}#mermaid-svg-kQLDerny1WmXB89O .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kQLDerny1WmXB89O .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kQLDerny1WmXB89O .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kQLDerny1WmXB89O .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kQLDerny1WmXB89O .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kQLDerny1WmXB89O .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kQLDerny1WmXB89O .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kQLDerny1WmXB89O .cluster text{fill:#333;}#mermaid-svg-kQLDerny1WmXB89O .cluster span{color:#333;}#mermaid-svg-kQLDerny1WmXB89O 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-kQLDerny1WmXB89O .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kQLDerny1WmXB89O rect.text{fill:none;stroke-width:0;}#mermaid-svg-kQLDerny1WmXB89O .icon-shape,#mermaid-svg-kQLDerny1WmXB89O .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kQLDerny1WmXB89O .icon-shape p,#mermaid-svg-kQLDerny1WmXB89O .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kQLDerny1WmXB89O .icon-shape .label rect,#mermaid-svg-kQLDerny1WmXB89O .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kQLDerny1WmXB89O .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kQLDerny1WmXB89O .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kQLDerny1WmXB89O :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SSH 连接
服务器验证用户身份
客户端验证服务器身份
服务器读取 authorized_keys
用用户公钥验证客户端签名
客户端读取 known_hosts
比对服务器主机公钥

第一次 SSH 到一台新机器时,常见提示是:

text 复制代码
The authenticity of host ... can't be established.

这表示本机还没有记录过这台服务器的主机公钥。确认后会写入 known_hosts

如果以后主机公钥变了,SSH 会强烈警告,因为可能是:

  • 服务器重装了,主机密钥变了。
  • DNS 或 IP 指到了另一台机器。
  • 可能遭遇中间人攻击。

12. HTTPS 证书和 SSH key 的区别

对比点 HTTPS/TLS 证书 SSH key
信任来源 CA 体系,系统/浏览器内置信任根 通常是手动信任或管理员配置
证明对象 域名/组织和公钥的绑定 用户身份或服务器主机身份
常见文件格式 X.509、PEM、DER、PKCS#12 OpenSSH key、PEM
典型验证 浏览器验证证书链和域名 服务器验证用户公钥,客户端验证主机公钥
是否需要 CA 公网 HTTPS 通常需要 普通 SSH 登录通常不需要

简单区分:

text 复制代码
HTTPS:浏览器问 CA,这个域名的公钥可信吗?
SSH:服务器问 authorized_keys,这个用户的公钥允许登录吗?
SSH 客户端还会问 known_hosts,这台服务器是不是我以前见过的那台?

13. 常见文件格式和后缀

后缀/格式 含义
.pem Base64 文本封装,常见于证书和私钥
.der 二进制证书/密钥编码
.crt / .cer 证书文件,可能是 PEM 或 DER
.key 私钥文件,格式不一定
.csr 证书签名请求
.p12 / .pfx PKCS#12,常用于打包证书、私钥和证书链
.pub 公钥文件,SSH 常见
known_hosts SSH 服务器主机公钥记录
authorized_keys SSH 允许登录的用户公钥列表

PEM 长这样:

text 复制代码
-----BEGIN CERTIFICATE-----
Base64...
-----END CERTIFICATE-----

OpenSSH 私钥可能长这样:

text 复制代码
-----BEGIN OPENSSH PRIVATE KEY-----
Base64...
-----END OPENSSH PRIVATE KEY-----

注意:PEM、DER、Base64 是编码或封装格式,不等于加密算法。

14. JWT 里的签名算法

JWT 的 alg 也经常让人混乱。

JWT alg 类型 说明
HS256 HMAC 使用共享密钥,签发方和验证方都知道 secret
RS256 RSA 签名 私钥签发,公钥验证
ES256 ECDSA P-256 私钥签发,公钥验证
EdDSA Ed25519 等 现代签名算法
none 无签名 正常业务系统不应该接受

关键区别:

  • HS256 是对称的,验证方知道 secret,也就有能力签发 token。
  • RS256、ES256、EdDSA 是非对称的,可以只把公钥发给验证方。

微服务里如果只有认证服务负责签发 token,其他服务只验证 token,通常更适合使用非对称签名。

15. 实际使用时怎么选

  • 传输加密优先用 TLS 1.3,不要自己设计传输加密协议。
  • 文件或字段加密优先用成熟库的 AEAD 接口,例如 AES-GCM 或 ChaCha20-Poly1305。
  • nonce/IV 不能重复,密钥不要硬编码进代码仓库。
  • 密码存储优先 Argon2id;不要直接存 MD5(password)SHA1(password)SHA256(password)
  • 数字签名新系统可优先 Ed25519;需要兼容证书、TLS、JWT 生态时,再按场景选择 RSA-PSS、RS256 或 ES256。
  • SSH 新生成用户 key 优先 Ed25519,私钥建议设置 passphrase,不要共享私钥。
  • 公网 HTTPS 使用可信 CA 签发的证书,注意 SAN、证书链和自动续期监控。

16. 常见误区清单

  • "Base64 加密":错。Base64 是编码。
  • "MD5 加密":错。MD5 是哈希,而且不适合安全用途。
  • "哈希可以解密":错。哈希是单向摘要。
  • "签名会隐藏内容":错。签名证明身份和完整性,不负责保密。
  • "HTTPS 用 RSA 加密所有数据":不准确。现代 HTTPS 通常用 ECDHE/X25519 做密钥交换,用 AES-GCM 或 ChaCha20-Poly1305 加密数据。
  • "证书就是公钥":不完整。证书包含公钥、主体、有效期、用途,并由 CA 签名。
  • "有证书就一定安全":不一定。还要看私钥是否泄露、域名是否匹配、证书链是否可信、TLS 配置是否安全。
  • "Ed25519 和 X25519 差不多":名字像,但用途不同。Ed25519 用于签名,X25519 用于密钥交换。

17. 口诀总结

text 复制代码
加密管保密,哈希管指纹。
HMAC 靠共享密钥,签名靠私钥和公钥。
证书把域名和公钥绑起来,CA 负责背书。
HTTPS 先认证和协商密钥,再用对称加密传数据。
SSH 私钥在本机,公钥放远端。
known_hosts 认服务器,authorized_keys 认用户。

如果只保留最小心智模型:

  1. 对称加密快,适合加密大量数据。
  2. 非对称体系慢,但适合身份认证、签名和密钥交换。
  3. 哈希是指纹,不能解密。
  4. HMAC 是带共享密钥的完整性认证。
  5. 数字签名是私钥签、公钥验。
  6. TLS/HTTPS 组合使用证书、签名、密钥交换、密钥派生和 AEAD。
  7. CA 证书体系解决"这个公钥到底是谁的"。
  8. SSH 登录靠私钥签名,不是传输私钥。

参考资料