前言

ECDHE 我之前是听都没听过, 但是新业务需要对前后端通信进行加密, 经过大佬推荐才知道有这个东西, 经过几天的学习和踩坑, 才大致明白其流程和使用方式.

过程坎坷, 好在最后还是成功运用到了业务中, 大大提高了业务的安全性.

这里记录一下本人对 ECDHE 的理解和注意要点

ECDHE

椭圆曲线迪菲-赫尔曼金钥交换 - 维基百科,自由的百科全书 (wikipedia.org)

我们先来说说 ECDH, ECDH(Elliptic Curve Diffie–Hellman key exchange) 是一种密钥协商协议, 其精髓是通过椭圆曲线算法(ECC), 让客户端和服务端不传输私钥(需要传输公钥), 就可以计算出一样的结果(共有加密资料), 即使协商过程被第三方(中间人)知晓和监听, 也不会泄露密钥.

而 ECDHE(ECDH Ephemeral) 与 ECDH 无本质差别, 他们协商的流程一模一样, 只是ECDHE代表协商出的共有加密资料是临时的, 就算当前的加密资料泄露, 也不会影响其之前的历史数据被解密, 这是使用方式决定的, 大白话意思就是, 我们通过 ECDH 生成的共有加密数据有实效性, 会通过逻辑在一段时间或特定事件后重新协商, 而不是只协商一次, 如果只协商一次, 如果共有加密资料被泄露, 则之前的所有数据都可以解开. 这种共有加密数据资料泄露也不会对历史数据有影响的特性在密码学中被称为 前向安全性.

椭圆曲线密码学(ECC)

ECC 是 ECDH 的核心

椭圆曲线密码学 - 维基百科,自由的百科全书 (wikipedia.org)

JavaScript ECDH Key Exchange Demo (stanford.edu)

椭圆曲线算法(ECC) 是一种基于椭圆曲线数学的公开密钥加密算法, ECC 相比于 RSA 来讲, 有更短的密钥长度和相同等级的安全性(ECC被广泛认为是在给定密钥长度的情况下,最强大的非对称算法,因此在对带宽要求十分紧的连接中会十分有用.)

而且, ECC可以定义群之间的双线性映射, 即通过两个向量空间上的元素, 生成第三个向量空间上的元素的函数. 这使得他可以让两对数据通过交换和计算得出相同结果

ECC 算法衍生出了一些加密协议, 常见的有 ECDHE, MQV, ECDSA 等

  • ECC 的公钥其实对应了椭圆曲线数学的 XY 坐标, 根据种子随机生成
  • ECC 的私钥对应了椭圆曲线数学的 a 参数, 与公钥对应
  • ECC 计算出的 share 也是 XY 坐标
  • ECC 的种子有公开的几个, 例如secp128r1/secp256r1/secp192k1

椭圆曲线数学

椭圆曲线的数学原理在这里

椭圆曲线 - 维基百科,自由的百科全书 (wikipedia.org)

常言道, 学好数理化, 走遍天下都不怕. 可惜我是宅男, 不爱出门

这个原理在我的理解范畴之外了, 如果你对数学有兴趣, 可以尝试了解

三者关系

先诞生出的椭圆曲线数学公式, 而后有的基于椭圆曲线数学公式的密码学算法 ECC, 而ECC 又衍生出一些加密协议和协议, ECDH就是其中一种

破解概率

直接引用 wiki 原文

如果攻击者拥有大型量子计算机,那么他可以使用秀尔算法解决离散对数问题,从而破解私钥和共享秘密。目前的估算认为:破解256位素数域上的椭圆曲线,需要2330个量子比特与1260亿个托佛利门。相比之下,使用秀尔算法破解2048位的RSA则需要4098个量子比特与5.2万亿个托佛利门。因此,椭圆曲线会更先遭到量子计算机的破解。目前还不存在建造如此大型量子计算机的科学技术,因此椭圆曲线密码学至少在未来十年(或更久)依然是安全的。但是密码学家已经积极展开了后量子密码学的研究。其中,超奇异椭圆曲线同源密钥交换(SIDH)有望取代当前的常规椭圆曲线密钥交换(ECDH)

ECDH 协商流程

前面说过, ECDHE 和 ECDH 不同是协商出的密钥有效期, 实际上协商流程是一致的, 所以这里严谨一点, 就叫 ECDH 协商流程

ECDH 本身的协商流程如下图所示(按照数字编号走流程):



上面说过, ECDH实际上是协商共享加密数据的过程, 难点在 ECC 的本身实现, 而交换的过程很简单, 互相发送自己生成的公钥即可, 公钥其实就是椭圆算法中的计算所需的 X/Y 坐标.

安全性

中间人只监听数据

两端协商密钥的过程中, 均未传输自己的私钥.

这样, 即使有中间人监听了两端之间的网络数据, 也只能获取到两端的公钥, 无法计算出真正的 shareX/shareY , 如图所示:

中间人监听并伪造客户端和服务端

如果中间人能做到, 同时伪造成客户端和服务端(对于客户端来讲是服务端, 对于服务端来讲是客户端), 那么ECDH生成的共享加密数据, 客户端与服务端无法对应

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

不过, 这就逃脱了 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 进行前后端通信数据加密

我们可以仿造 TLS1.2 协议来打造一个前后端通信加密的流程, 但是需要注意以下几点:

  • ECDH 本身的协商过程是"明文的", 协商出共享加密数据后使用该数据对 body 进行加密传输才是"安全的"
  • ECDH 变成 ECDHE 是加了时效性, 因此共享加密数据的淘汰策略很重要
  • ECC 生成的公私钥实际上是 XY 坐标, 考虑前端 JS 出问题生成 XY 重复的可能

    修改后的密钥协商流程如下:

针对问题1, 我们使用混淆生成 key 进行 aes 加密的方式, 对请求进行加密, 提高解密难度

针对问题2, 我们将单次协商的共享密钥与当前会话绑定, 并对会话进行有效期淘汰管理

针对问题3, 我们在前后端加入随机数生成并于最终的 shareX 混淆, 防止ECC生成公私钥时因实现问题导致的重复密钥

浅尝 ECDHE 协议流程的更多相关文章

  1. 浅尝ECMAScript6

    浅尝ECMAScript6 简介 ECMAScript6 是最新的ECMAScript标准,于2015年6月正式推出(所以也称为ECMAScript 2015),相比于2009年推出的es5, es6 ...

  2. 浅尝Go语言GC

    大家好,我是小栈君,因为个人和工作的缘故,所以拖更了一点时间,但是关于拖更的内容小栈君会在后续的时间中补回来,还希望大家继续支持和关注小栈君.当然,在国内疫情稍微减缓的情况下,小栈君在这里也多说两句, ...

  3. 浅尝装饰器和AOP

    [写在前面] 参考文章:https://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html[从简单的例子入手进行讲解,由浅入深,很到位] 装饰器部 ...

  4. 浅尝Spring注解开发_Bean生命周期及执行过程

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...

  5. 浅尝Spring注解开发_AOP原理及完整过程分析(源码)

    浅尝Spring注解开发_AOP原理及完整过程分析(源码) 浅尝Spring注解开发,基于Spring 4.3.12 分析AOP执行过程及源码,包含AOP注解使用.AOP原理.分析Annotation ...

  6. 浅尝Spring注解开发_Servlet3.0与SpringMVC

    浅尝Spring注解开发_Servlet 3.0 与 SpringMVC 浅尝Spring注解开发,基于Spring 4.3.12 Servlet3.0新增了注解支持.异步处理,可以省去web.xml ...

  7. 【转】 浅谈Radius协议

    浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报  分类: Radius协议分析(6)  从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...

  8. 转:浅谈Radius协议 -来自CSDN:http://blog.csdn.net/wangpengqi/article/details/17097221

    浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报  分类: Radius协议分析(6)  从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...

  9. 浅尝key-value数据库(二)——MongoDB的优与劣

    浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...

随机推荐

  1. Luogu5020 货币系统 (完全背包)

    bool型完全背包 #include <iostream> #include <cstdio> #include <cstring> #include <al ...

  2. java-代码操作服务器之SSH连续发送命令

    java操作Linux服务器可以使用专用的jar包,这里介绍使用jsch操作Linux服务器 maven 依赖 <dependency> <groupId>com.jcraft ...

  3. 原生应用、Web 应用和混合应用的概念,以及 Flutter 技术是什么

    应用类型 原生应用 原生应用就是使用特定的语言开发的应用,例如 Android 原生应用.Windows 原生应用.iOS 原生应用等.开发 Android 原生应用时,其特定的编程语言为 Java ...

  4. 七分钟学会 HTML 网页制作

    什么是HTML 点击打开视频讲解更加详细 Hyper Text Markup Language(超文本标记语言) 标签控制排版 体积小,方便传输 编写HTLML 推荐使用:VS Code <!D ...

  5. redis-hash命令

    一.HDEL key field [field ...] 从 key 指定的哈希集中移除指定的域.在哈希集中不存在的域将被忽略. 如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将 ...

  6. Html5新增内容标签

    <canvas>画布</canvas> <audio src=""></audio> <video src="&qu ...

  7. 前端Long类型丢失精度问题

    有时候后端向前端传输Long类型,数字过长会出现丢失精度的问题 比如后端传来的是这样一个长数字串 那么前端的弹窗显示的是 ![](https://img2022.cnblogs.com/blog/22 ...

  8. Jenkins JNLP方式启动 Agent

    Jenkins Server配置 如果你是通过Nginx代理了jenkins,那么需要调整下Nginx的配置 map $http_upgrade $connection_upgrade { defau ...

  9. limits.conf 配置不生效问题排查

    在部署数据库时,经常会遇到打开最大文件数限制 too many open files 的警告,通常我们只需要修改/etc/security/limits.conf该文件,增加两行,重新登录即可解决. ...

  10. 使用『jQuery』『原生js』制作一个导航栏动效 —— { }

    效果 HTML部分 <body> <nav> <div id="nav1">导航1</div> <div id="n ...