前言

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. 一个监控工具monit

    最近看了一个问题,monit监控在读取配置文件之后,访问的文件是残留在容器中的,导致认为服务异常,其实一开始容器启动,并没有对应的服务. [root@10-36-235-119.fin-wealth- ...

  2. 【Java】学习路径48-线程锁ReentrantLock

    与上一章学习的线程锁synchronized类似,都是为了解决线程安全的问题. 使用方法: 新建一个ReentrantLock对象.(如果使用Thread多线程,则需要声明static静态) 然后在需 ...

  3. 抛砖系列之git仓库拆分工具git-filter-repo

    最近负责把团队内的git仓库做了一次分拆,解锁一个好用的工具git-filter-repo,给大伙抛砖一波,希望以后遇到类似场景时可以信手拈来. 背景 笔者团队目前是把业务相关的java项目都放到了一 ...

  4. Linux软件包常见的几种下载、安装方法

    在线源下载和安装 如果服务器是处于在线状态,在使用默认下载源是外国的情况下,安装更新软件包往往会比较痛苦的存在,下载了许久来一个超时就gg了.国内有许多镜像源,完美的解决了这个问题. 对于rpm系列的 ...

  5. VS Code中Markdown常用插件

    目录 目录 1.Markdown All in One 2.Markdown Preview Enhanced 3.markdownlint 1.Markdown All in One 自动生成目录 ...

  6. DS

    树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...

  7. 【读书笔记】C#高级编程 第六章 数组

    (一)同一类型和不同类型的多个对象 如果需要使用同一类型的多个对象,就可以使用数组或集合(后面章讲). 如果需要使用不同类型的多个对象,可以使用Tuple(元组)类型. (二)简单数组 如果需要使用同 ...

  8. cnblogs-theme-blogure

    cnblogs-theme-blogure 又一个博客园主题 Blogure. 它使用 PetiteVue 和 PicoCSS. 喜欢的话可以帮个点 Star 么? 快速开始 确保博客园有 JS 权限 ...

  9. 内存溢出(OOM)分析

    当JVM内存不足时,会抛出java.lang.OutOfMemoryError.   主要的OOM类型右: Java heap space:堆空间不足 GC overhead limit exceed ...

  10. CAP 6.2 版本发布通告

    前言 今天,我们很高兴宣布 CAP 发布 6.2 版本正式版,在这个版本中我们主要做了一些功能优化,以及针对目前已经发现的几个 BUG 进行了修复了. 那么,接下来我们具体看一下吧. 总览 可能有些人 ...