非对称加密有两把钥匙:公钥和私钥,成对生成。
- 公钥 --- 公开,用来加密和验证
- 私钥 --- 仅自己持有,用来解密和签名
为什么说公钥是验证而不是解密?
公钥本质上不是在解密,是在验证消息是持有私钥的发送方发来的。
1. 以 HTTPS 加解密为例
服务端 客户端 服务端 客户端 #mermaid-svg-ctQIFk3inA8orzZc{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-ctQIFk3inA8orzZc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ctQIFk3inA8orzZc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ctQIFk3inA8orzZc .error-icon{fill:#552222;}#mermaid-svg-ctQIFk3inA8orzZc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ctQIFk3inA8orzZc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ctQIFk3inA8orzZc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ctQIFk3inA8orzZc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ctQIFk3inA8orzZc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ctQIFk3inA8orzZc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ctQIFk3inA8orzZc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ctQIFk3inA8orzZc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ctQIFk3inA8orzZc .marker.cross{stroke:#333333;}#mermaid-svg-ctQIFk3inA8orzZc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ctQIFk3inA8orzZc p{margin:0;}#mermaid-svg-ctQIFk3inA8orzZc .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ctQIFk3inA8orzZc text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-ctQIFk3inA8orzZc .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ctQIFk3inA8orzZc .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-ctQIFk3inA8orzZc .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ctQIFk3inA8orzZc .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ctQIFk3inA8orzZc #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ctQIFk3inA8orzZc .sequenceNumber{fill:white;}#mermaid-svg-ctQIFk3inA8orzZc #sequencenumber{fill:#333;}#mermaid-svg-ctQIFk3inA8orzZc #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ctQIFk3inA8orzZc .messageText{fill:#333;stroke:none;}#mermaid-svg-ctQIFk3inA8orzZc .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ctQIFk3inA8orzZc .labelText,#mermaid-svg-ctQIFk3inA8orzZc .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-ctQIFk3inA8orzZc .loopText,#mermaid-svg-ctQIFk3inA8orzZc .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-ctQIFk3inA8orzZc .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-ctQIFk3inA8orzZc .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ctQIFk3inA8orzZc .noteText,#mermaid-svg-ctQIFk3inA8orzZc .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-ctQIFk3inA8orzZc .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ctQIFk3inA8orzZc .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ctQIFk3inA8orzZc .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ctQIFk3inA8orzZc .actorPopupMenu{position:absolute;}#mermaid-svg-ctQIFk3inA8orzZc .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-ctQIFk3inA8orzZc .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ctQIFk3inA8orzZc .actor-man circle,#mermaid-svg-ctQIFk3inA8orzZc line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ctQIFk3inA8orzZc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TCP 三次握手 TLS 建立(非对称加密) 对称密钥 K 就绪,加密通信 SYNSYN + ACKACKClientHelloServerHello + 证书验证证书公钥 A公钥 B
1.2 数字签名验证流程
数字签名是为了验证身份,不是为了内容保密。
接收方(持有公钥) 发送方(持有私钥) 接收方(持有公钥) 发送方(持有私钥) #mermaid-svg-3VwOeQAhQhxrkGP0{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-3VwOeQAhQhxrkGP0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3VwOeQAhQhxrkGP0 .error-icon{fill:#552222;}#mermaid-svg-3VwOeQAhQhxrkGP0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3VwOeQAhQhxrkGP0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3VwOeQAhQhxrkGP0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3VwOeQAhQhxrkGP0 .marker.cross{stroke:#333333;}#mermaid-svg-3VwOeQAhQhxrkGP0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3VwOeQAhQhxrkGP0 p{margin:0;}#mermaid-svg-3VwOeQAhQhxrkGP0 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3VwOeQAhQhxrkGP0 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-3VwOeQAhQhxrkGP0 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-3VwOeQAhQhxrkGP0 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-3VwOeQAhQhxrkGP0 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-3VwOeQAhQhxrkGP0 .sequenceNumber{fill:white;}#mermaid-svg-3VwOeQAhQhxrkGP0 #sequencenumber{fill:#333;}#mermaid-svg-3VwOeQAhQhxrkGP0 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-3VwOeQAhQhxrkGP0 .messageText{fill:#333;stroke:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3VwOeQAhQhxrkGP0 .labelText,#mermaid-svg-3VwOeQAhQhxrkGP0 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .loopText,#mermaid-svg-3VwOeQAhQhxrkGP0 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .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-3VwOeQAhQhxrkGP0 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-3VwOeQAhQhxrkGP0 .noteText,#mermaid-svg-3VwOeQAhQhxrkGP0 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-3VwOeQAhQhxrkGP0 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3VwOeQAhQhxrkGP0 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3VwOeQAhQhxrkGP0 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3VwOeQAhQhxrkGP0 .actorPopupMenu{position:absolute;}#mermaid-svg-3VwOeQAhQhxrkGP0 .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-3VwOeQAhQhxrkGP0 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3VwOeQAhQhxrkGP0 .actor-man circle,#mermaid-svg-3VwOeQAhQhxrkGP0 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-3VwOeQAhQhxrkGP0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 原文 + 私钥 → 签名 公钥对签名算得到A 约定算法对原文算得到A' 验证 A == A' ? 发送 原文 + 签名
- 原文是明文传输的,黑客拿到也没关系。这个场景只为了验证身份,不是为了内容保密。
1.3 ECDHE 密钥交换流程
这个阶段是为了交换密钥对,密钥对将来会用于对称加密。
服务端 客户端 服务端 客户端 #mermaid-svg-IcJ9fYblbqaatVDA{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-IcJ9fYblbqaatVDA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IcJ9fYblbqaatVDA .error-icon{fill:#552222;}#mermaid-svg-IcJ9fYblbqaatVDA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IcJ9fYblbqaatVDA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IcJ9fYblbqaatVDA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IcJ9fYblbqaatVDA .marker.cross{stroke:#333333;}#mermaid-svg-IcJ9fYblbqaatVDA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IcJ9fYblbqaatVDA p{margin:0;}#mermaid-svg-IcJ9fYblbqaatVDA .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IcJ9fYblbqaatVDA text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-IcJ9fYblbqaatVDA .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IcJ9fYblbqaatVDA .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-IcJ9fYblbqaatVDA .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-IcJ9fYblbqaatVDA .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-IcJ9fYblbqaatVDA #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-IcJ9fYblbqaatVDA .sequenceNumber{fill:white;}#mermaid-svg-IcJ9fYblbqaatVDA #sequencenumber{fill:#333;}#mermaid-svg-IcJ9fYblbqaatVDA #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-IcJ9fYblbqaatVDA .messageText{fill:#333;stroke:none;}#mermaid-svg-IcJ9fYblbqaatVDA .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IcJ9fYblbqaatVDA .labelText,#mermaid-svg-IcJ9fYblbqaatVDA .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-IcJ9fYblbqaatVDA .loopText,#mermaid-svg-IcJ9fYblbqaatVDA .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-IcJ9fYblbqaatVDA .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-IcJ9fYblbqaatVDA .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-IcJ9fYblbqaatVDA .noteText,#mermaid-svg-IcJ9fYblbqaatVDA .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-IcJ9fYblbqaatVDA .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IcJ9fYblbqaatVDA .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IcJ9fYblbqaatVDA .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IcJ9fYblbqaatVDA .actorPopupMenu{position:absolute;}#mermaid-svg-IcJ9fYblbqaatVDA .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-IcJ9fYblbqaatVDA .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IcJ9fYblbqaatVDA .actor-man circle,#mermaid-svg-IcJ9fYblbqaatVDA line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-IcJ9fYblbqaatVDA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 生成临时私钥 a,算公钥 A = g^a 生成临时私钥 b,算公钥 B = g^b 收到 B,用自己的私钥 a 算 K = B^a = g^(ab) 收到 A,用自己的私钥 b 算 K = A^b = g^(ab) 双方得到相同的 K,作为对称密钥 发送公钥 A发送公钥 B