浅尝 ECDHE 协议流程( 二 )


浅尝 ECDHE 协议流程

文章插图
上面说过, ECDH实际上是协商共享加密数据的过程, 难点在 ECC 的本身实现, 而交换的过程很简单, 互相发送自己生成的公钥即可, 公钥其实就是椭圆算法中的计算所需的 X/Y 坐标.
安全性中间人只监听数据两端协商密钥的过程中, 均未传输自己的私钥.这样, 即使有中间人监听了两端之间的网络数据, 也只能获取到两端的公钥, 无法计算出真正的 shareX/shareY , 如图所示:
浅尝 ECDHE 协议流程

文章插图
中间人监听并伪造客户端和服务端如果中间人能做到, 同时伪造成客户端和服务端(对于客户端来讲是服务端, 对于服务端来讲是客户端), 那么ECDH生成的共享加密数据, 客户端与服务端无法对应
浅尝 ECDHE 协议流程

文章插图
但是细想, 这时候, 虽然客户端与服务端的共享加密数据不相同, 但是ECDH只是一个协商密钥的过程, 中间人在此种情况下成功在客户端与服务端不知情的情况下正常走完了协商流程, 之后的加密数据, 如果使用了这个协商出的加密数据, 就会导致之后的数据被中间人截获/解析, 并且无感知, 例如:
浅尝 ECDHE 协议流程

文章插图
不过, 这就逃脱了 ECDH 的范畴了, 这是真正需要开发者在业务中考虑的事情.
ECDH在 TLS1.2 中的使用流程TLS1.2 的详细立案可看:RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 (rfc-editor.org)在 TLS1.2 协议中, 就使用了 ECDHE 来交换密钥, 我们来分析一下 TLS1.2 怎么使用 ECDHE 的:TLS v1.2 handshake overview | by apoorv munshi | Medium如文章所述, 在步骤 Server Key Exchange & Server Hello Done 时, 服务端不止返回了自己的 ECC 公钥, 还使用了 TLS 证书生成时的私钥对信息进行了签名(RSA), 而后, 客户端在接受到信息后, 尝试使用 TLS 证书中的公钥对信息进行验签, 用来保证数据一定是服务端返回的, 解决中间人篡改问题, 如图:
浅尝 ECDHE 协议流程

文章插图
业务中使用 ECDHE 进行前后端通信数据加密我们可以仿造 TLS1.2 协议来打造一个前后端通信加密的流程, 但是需要注意以下几点:
  • ECDH 本身的协商过程是"明文的", 协商出共享加密数据后使用该数据对 body 进行加密传输才是"安全的"
  • ECDH 变成 ECDHE 是加了时效性, 因此共享加密数据的淘汰策略很重要
  • ECC 生成的公私钥实际上是 XY 坐标, 考虑前端 JS 出问题生成 XY 重复的可能修改后的密钥协商流程如下:
    浅尝 ECDHE 协议流程

    文章插图
针对问题1, 我们使用混淆生成 key 进行 aes 加密的方式, 对请求进行加密, 提高解密难度针对问题2, 我们将单次协商的共享密钥与当前会话绑定, 并对会话进行有效期淘汰管理针对问题3, 我们在前后端加入随机数生成并于最终的 shareX 混淆, 防止ECC生成公私钥时因实现问题导致的重复密钥
【浅尝 ECDHE 协议流程】

经验总结扩展阅读