为什么是椭圆曲线加密?

椭圆曲线加密(以下简称ECC)实际上已经应用到了各个网站的HTTPS连接中。你平常访问的网站,大部分都是基于椭圆曲线加密,比如你现在正在浏览的CSDN。如果你用的是chrome浏览器,按下F12,点开Security,可以看到下图这样的内容:

这里的ECDHE就是椭圆曲线密钥交换的简称。能进行密钥交换的算法并非只有ECC,但是现在的大型网站(除了某些老旧的银行网站)都不约而同地选择了ECC。还有大火的比特币,先不论比特币的争议,设计相当精妙,其身份认证机制便是以ECC为基础。为何比特币选择的也是ECC?

如果你是一个服务端程序员或者运维人员,那么肯定没少用SSH连接服务器。SSH连接里面经常会用公钥进行登录。这时会要求先在本机使用ssh-keygen生成密钥对,然后把密钥对里的公钥上传到服务器。但是用多了有没有发现ssh-keygen默认生成的密钥有点长?比如这个公钥:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCypa+az50x7bi0vweyY2dVQIztS9Q/v4DL3OQMPCPDR85bFsvsXWB5r/fbETDlo25ZDyWBInOVxqR96H0vKeWE28tbbQSqne41WAobPe1Z4gxq5o2WJXsC44qjW9ne34dJFVYNX9DrcnvddyZdTxw4Apa6A/hixMtaPDueQF6lct8EsVhkRqFSbdYfumABxUlGW4kKbwA86zT+jDCbnOHyk7EOvtUuLqlTntZmko7gm46QSuYNuhlFeGQirzmVmU8C55wABvVjeVw/wXZe96Q5faPEqAvY+X3o0ku1eliQuI/7BGq9j9s8q2WqSTBweOhJ5mHhf+kyra0jm70WYRlb

但是你只需要把ssh-keygen的密钥类型从默认的RSA切换到ECC,也就是运行ssh-keygen -t ed25519,就可以得到一个短得多的公钥:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHzJZ8pHw7wVIFWp9zmLIeYyhk81QAp42FuCQkdbG1bb

一般来说,密钥越长安全性越高,但是这个短密钥的安全性比上面长的还要高。破解它的难度相当于破解长度为3000位(二进制位)的RSA密钥。而ssh-keygen默认生成的是长度为2048位的RSA密钥。为什么ECC的密钥可以这么短但是安全性却更高?

序言


不管是RSA、离散对数加密还是椭圆曲线加密,公钥加密算法都是依赖于某个正向计算很简单(比如多项式时间复杂度),而逆向计算很难(比如指数时间复杂度)的数学难题。对于RSA,这个问题是大整数因子分解问题;对于离散对数加密,是离散对数问题;对于椭圆曲线加密,则是椭圆曲线上的离散对数问题。

本文主要介绍椭圆曲线加密,但是离散对数加密和椭圆曲线加密原理比较相似,在这里一起介绍。

离散对数问题


我们在中学里学的对数问题是指,

给定正实数aaa和axa^xax,求xxx。也就是计算x=log⁡aaxx=\log_a{a^x}x=loga​ax。

这是实数域上的对数问题,不是什么难算的东西,随便按一下计算器结果就出来了。

而离散对数问题是指这样的问题:

给定素数ppp和正整数ggg,知道gxmodpg^x\mod pgxmodp的值,求xxx

对于符合特定条件的ppp和ggg,这个问题是很难算的,更准确地说,是没有多项式时间的解法。而gxmodpg^x \mod pgxmodp的计算却非常快,由此造成了正向和逆向天差地别的计算速度。打个比方,就像随手一扔,玻璃杯就摔碎成渣,而想要将一堆玻璃渣拼回完整的玻璃杯,即使做得到,所需的人力物力也远远大于当初那随手一扔。

Diffie–Hellman密钥交换


Diffie–Hellman密钥交换(以下简称DH)是用于双方在可能被窃听环境下安全交换密钥的一种方法。
算法的安全性是由上面提到的离散对数难题保证。

具体算法流程如下:

  • 小红和小明约定ppp和ggg的值
  • 小红生成私钥xxx,计算gxmodpg^x\mod pgxmodp作为公钥公布出去
  • 小明生成私钥yyy,计算gymodpg^y\mod pgymodp作为公钥公布出去
  • 小红得知gymodpg^y\mod pgymodp后,计算
    s=(gymodp)xmodp=(gy)xmodp=gxymodps=(g^y\mod p)^x\mod p=(g^y)^x\mod p=g^{xy}\mod ps=(gymodp)xmodp=(gy)xmodp=gxymodp
  • 小明得到gxmodpg^x\mod pgxmodp后,计算
    s=(gxmodp)ymodp=(gx)ymodp=gxymodps=(g^x\mod p)^y\mod p=(g^x)^y\mod p=g^{xy}\mod ps=(gxmodp)ymodp=(gx)ymodp=gxymodp
  • 双方都得到了相同的密钥的sss,交换完毕

上面的流程中,xxx和yyy始终由两人自行保管的,第三方窃听得到的只有ppp、ggg、gxmodpg^x\mod pgxmodp和gymodpg^y\mod pgymodp这几个值。
上面说过,离散对数是很难算的,所以第三方不能由这些信息计算出xxx或yyy,也就没办法计算出密钥sss了。

椭圆曲线


中学的时候我们学过圆锥曲线,比如椭圆、双曲线和抛物线。因为描述这些曲线的方程都是二次方程,圆锥曲线又被称为二次曲线。而椭圆曲线是则是由三次方程描述的一些曲线。更准确地说,椭圆曲线是由下面的方程描述的曲线:
y2=x3+ax+b4a3+27b2≠0y^2=x^3+ax+b\\ 4a^3+27b^2 \neq 0y2=x3+ax+b4a3+27b2​=0

需要注意的是,椭圆曲线之所以叫“椭圆曲线”,是因为其曲线方程跟利用微积分计算椭圆周长的公式相似。实际上它的图像跟椭圆完全不搭边。

下图是椭圆曲线y2=x3−x+1y^2=x^3-x+1y2=x3−x+1的图像

椭圆曲线有这样的两个性质:

  1. 关于X轴对称
  2. 画一条直线跟椭圆曲线相交,它们最多有三个交点

椭圆曲线上的运算


椭圆曲线加密之所以难破解,是因为其加密、解密运算是在椭圆曲线上进行的,所以接下来需要定义一些椭圆曲线上的运算。可以回想一下小学的时候第一次学整数加减法的情景,两者其实是类似的。

首先定义椭圆曲线上点的加法。设椭圆曲线上有两点,A和B点,那么作过这两点的直线与该曲线相交于第三点(C点),然后关于X轴对称得到D点,则D为这两个点的和,记作D=A+BD=A+BD=A+B。很明显,D点也在该曲线上。所以椭圆曲线上两点之和也是曲线上的点。、

这个性质我们称之为封闭性,也就是只要A和B是曲线上的点,他们的和也必然是曲线上的点。类比于整数加法,只要相加的两个数是整数,那么他们的和也必然是整数。

特别地,如果两点重合,则作椭圆曲线在A点处的切线,与曲线相交于第二点(B点),然后关于X轴对称得到C点,则C点为A点与自身的和,记作C=A+AC=A+AC=A+A

看到这里很多人可能会觉得疑惑,为什么要定义一个这么奇怪的加法?
实际上这个加法来源于椭圆曲线上利用已知有理点(横、纵坐标都是有理数的点)寻找其它有理点的方法,叫切线法(tangent and chord method)。这种加法可以保证以下两个结论是成立的:

  1. A+B=B+AA+B=B+AA+B=B+A
    交换律。这是显而易见的,直线没有方向,过A点作直线经过B点,和过B点作直线经过A点,得到的是同一条直线。
  2. (A+B)+C=A+(B+C)(A+B)+C=A+(B+C)(A+B)+C=A+(B+C)
    结合律。读者可以到GeoGebra自己试着画一下。这个结论的证明并不直观,详细的过程可以参考这里。

这个时候聪明如你可能会发现,如果相加的两个点,A点和B点形成的直线恰好垂直于X轴,那么这条直线与椭圆曲线不管怎么算最多只有两个交点,上面的加法岂不是没法做了?为了补足这个缺陷,这里我们定义坐标系中距离X轴无穷远点为椭圆曲线上的一个特殊点,称为0点(零点)。 因为任意一条垂直于X轴的直线都会与椭圆曲线相交于0点。这里可能有点难以理解,实际上可以类比平面上平行线的定义。我们知道,两条直线必定有交点这一结论是错的,因为平行线是个例外。但是如果我们定义,两条平行的直线相交于无穷远点,那么这个结论就是成立的。

对于这个0点,有以下结论:

  1. 对于椭圆曲线上任意一点A,都存在曲线上另一点B,使得A+B=0A+B=0A+B=0
    因为椭圆曲线关于X轴对称,所以对于曲线上任意一点A,总存在另一点B使得过A、B的直线垂直于X轴,也就是该直线与曲线交于0点,所以A+B=0
  2. A+0=0+A=AA+0=0+A=AA+0=0+A=A
    因为0点是距离X轴无穷远的点,所以过A点与0点的直线是垂直于X轴的,它与曲线相交于另一点B点,那么B点关于X轴对称的点就是A点,即A点为A点和0点之和。

    实际上这里“顺便”定义了椭圆曲线中的负数,若A+B=0A+B=0A+B=0,那么B=−AB=-AB=−A。椭圆曲线上点的减法也就自然而然地出现了,A−B=A+(−B)A-B=A+(-B)A−B=A+(−B)。

就这样,我们得到了一个新的加法运算“体系”,类似整数加法,它有零,满足交换律、结合律,还有对应的减法。只是里面的基本元素从整数变成椭圆曲线上的点,加法的运算也变得略微有点奇怪。

我们对这个“体系”进一步拓展,在加法的基础上,定义椭圆曲线上点的乘法

设PPP是椭圆曲线上的一个点,那么正整数kkk乘以点PPP的结果由下面的式子定义,注意式子中的加法是上面提到的椭圆曲线上点的加法:
1∗P=P1*P=P1∗P=P
2∗P=P+P2*P=P+P2∗P=P+P
3∗P=2∗P+P3*P=2*P+P3∗P=2∗P+P

k∗P=(k−1)∗P+Pk*P=(k-1)*P+Pk∗P=(k−1)∗P+P

这个乘法满足以下性质:

对于任意正整数kkk和jjj,有
k∗(j∗P)=(kj)∗P=(jk)∗P=j∗(k∗P)k*(j*P)=(kj)*P=(jk)*P=j*(k*P)k∗(j∗P)=(kj)∗P=(jk)∗P=j∗(k∗P)

这个性质在下文中的椭圆曲线密钥交换中会用到。

椭圆曲线上的离散对数问题


从程序实现的角度来考虑,假设有这么一个函数:

 Point add(Point A, Point B) {...}

函数参数是两个椭圆曲线上的点,返回值是过两个点的直线与椭圆曲线相交的第三个点关于X轴对称的点。
那么按照如下方式调用函数我们就实现了椭圆曲线上点的乘法:

Point result = P;
for (int i = 0; i < k - 1; i++)result = add(P, result);
sendTo((result, P), others);

但是很显然,通过累加k−1k-1k−1次的方式计算k∗Pk*Pk∗P是一种很笨的办法,其时间复杂度是线性的。上面我们提到过,椭圆曲线上点的加法是满足结合律的,即(A+B)+C=A+(B+C)(A+B)+C=A+(B+C)(A+B)+C=A+(B+C),扩展一下,就有

P+P+P+P=(P+P)+(P+P)=2P+2PP+P+P+P=(P+P)+(P+P)=2P+2PP+P+P+P=(P+P)+(P+P)=2P+2P

于是就有这么一种骚操作,比如计算16P16P16P,我们可以先计算2P=P+P2P=P+P2P=P+P;然后计算4P=P+P+P+P=2P+2P4P=P+P+P+P=2P+2P4P=P+P+P+P=2P+2P;再计算8P=P+P...+P=4P+4P8P=P+P...+P=4P+4P8P=P+P...+P=4P+4P;最后计算16P=8P+8P16P=8P+8P16P=8P+8P。这里我们把15次加法减少到了4次。

当然,k的值不可能总是2的幂。实际上上面的操作可以推广到k为任意正整数的情况。比如计算23P,首先计算2P=P+P,然后

4P=2P+2P4P=2P+2P4P=2P+2P

8P=4P+4P8P=4P+4P8P=4P+4P

16P=8P+8P16P=8P+8P16P=8P+8P

因为23=16+4+2+123=16+4+2+123=16+4+2+1,所以23P=16P+4P+2P+P23P=16P+4P+2P+P23P=16P+4P+2P+P。总共只需要7次加法。

分析一下,对于任意正整数kkk,我们都可以利用这个方法将计算k∗Pk*Pk∗P所需的加法计算次数降低到2⋅⌊log⁡2k⌋−12\cdot \lfloor \log_2k\rfloor-12⋅⌊log2​k⌋−1

也就是说,从时间复杂度的角度来看,这个算法是一个O(log⁡k)O(\log k)O(logk)的算法。

这个方法被称为快速幂算法,原本常用于快速计算某个数的k次幂,这里将其推广到椭圆曲线点乘的快速计算中。

为什么要在介绍了椭圆曲线上点的乘法后突然冒出一个快速幂算法?快速幂算法对于椭圆曲线加密有什么意义?因为密码学家发现,利用快速幂算法计算k∗Pk*Pk∗P的时间复杂度是对数级的,但是要在知道k∗Pk*Pk∗P和PPP的前提下,倒推出kkk的值,没有比挨个尝试kkk的值快太多的算法。于是椭圆曲线加密依赖的数学难题就这么诞生了。

kkk为正整数,PPP是椭圆曲线上的点(称为基点),已知k∗Pk*Pk∗P和PPP,计算kkk

如果我们改一种记法,把椭圆曲线上点的加法记作乘法,原来的乘法就变成了幂运算,那么上述难题的形式跟离散对数问题应该是一致的。即:

kkk为正整数,PPP是椭圆曲线上的点,已知PkP^kPk和PPP,计算k=log⁡PPkk=\log_PP^kk=logP​Pk。

所以这个难题叫椭圆曲线上的离散对数问题。

尽管两个的形式一致,但是他们并不等价。实际上这个问题比大整数质因子分解(RSA)和离散对数(DH)难题都要难不少,目前还没有出现亚指数级时间复杂度的算法(大整数质因子分解和离散对数问题都有),这就是文章开头提到的同样甚至更高的安全强度下,椭圆曲线加密的密钥比RSA和DH的短不少的原因。

有限域上的椭圆曲线


但是密码学中,并不能直接用上面说的实数域上的椭圆曲线。因为

  1. 实数域上的椭圆曲线是连续的,有无限个点,密码学要求有限点。
  2. 实数域上的椭圆曲线的运算有误差,不精确。密码学要求精确。

所以我们需要引入有限域上的椭圆曲线。

所谓有限域上的椭圆曲线,简单来说就是满足下面式子要求的曲线(x, y, a, b都是小于素数p的非负整数):
y2=x3+ax+bmodp其中4a3+27b2≠0modpy^2 =x^3+ax+b \mod p\\ 其中4a^3+27b^2\neq 0\mod py2=x3+ax+bmodp其中4a3+27b2​=0modp

对比一下原先的椭圆曲线的方程:
y2=x3+ax+b其中4a3+27b2≠0y^2=x^3+ax+b\\ 其中4a^3+27b^2\neq 0y2=x3+ax+b其中4a3+27b2​=0
可以看到这个只是对原式进行了简单的取模处理而已。实际上RSA和DH中也是基于这种形式的取模运算。

下图是椭圆曲线y2=x3−x+1y^2 = x^3 - x + 1y2=x3−x+1对素数97取模后的图像(图片来自参考文献)

原本连续光滑的曲线变成了离散的点,基本已经面目全非了,但是依然可以看到它是关于某条水平直线(y=97/2)对称的。

而且上面定义的椭圆曲线的加法仍然可用(当然乘法也可以)(图片来自参考文献)。

注意:密码学中有限域上的椭圆曲线一般有两种,一种是定义在以素数p为模的整数域GF(p)GF(p)GF(p),也就是上面介绍的;另一种则是定义在特征为2的伽罗瓦域GF(2m)GF(2^m)GF(2m)上,篇幅所限,这里就不介绍了。

基于椭圆曲线的DH密钥交换(ECDH)


ECDH跟DH的流程基本是一致的。

  • 小红和小明约定使用某条椭圆曲线(包括曲线参数,有限域参数以及基点P等)
  • 小红生成私钥xxx,计算x∗Px*Px∗P作为公钥公布出去
  • 小明生成私钥yyy,计算y∗Py*Py∗P作为公钥公布出去
  • 小红得知y∗Py*Py∗P后,计算
    s=x∗(y∗P)=xy∗Ps=x*(y*P)=xy*Ps=x∗(y∗P)=xy∗P
  • 小明得到x∗Px*Px∗P后,计算
    s=y∗(x∗P)=yx∗Ps=y*(x*P)=yx*Ps=y∗(x∗P)=yx∗P
  • 双方都得到了相同的密钥的sss,交换完毕

由于计算椭圆曲线上的离散对数是很难的,所以第三方没办法在只知道x∗Px*Px∗P和y∗Py*Py∗P的情况下计算出xxx或yyy的值。

实际业务应用中,我们不用管椭圆曲线这一堆参数该怎么选(要选对参数对于普通用户来说并不现实),已经有一大批现成的曲线,集成在OpenSSL之类的基础库里,从里面选一个就行了。比如prime256v1是比较常用的曲线,很多常见网站的ECC加密算法都是用的它;而Curve25519是比较新的曲线,安全性和效率都很高,而且密钥更短,现在颇受青睐。比特币用的是secp256k1,它效率比较高,更重要的是它的参数是通过可预测(predictable)的方式选出来的,大大降低了包含后门的可能性。相比之下有的曲线虽然至今还没被发现有安全性问题,但是他们的参数选择却一直无法给出有效的解释,所以经常被怀疑藏有后门。

参考文献

浅说椭圆曲线
A (relatively easy to understand) primer on elliptic curve cryptography
Wikipedia: Elliptic curve
Wikipedia: Elliptic curve cryptography
Bitcoin加密技术之椭圆曲线密码学
椭圆曲线密码体制

离散对数和椭圆曲线加密原理相关推荐

  1. 椭圆曲线加密原理与应用

    一. 概述 由于RSA.AES等国际算法面临高强度算法禁售和被部署后门风险,我国基于ECC椭圆曲线,自研SM2/SM3/SM4/SM9一套安全算法.根据国家整体战略,金融及重要领域要逐步实现国密算法替 ...

  2. 【密码学Sage代码】椭圆曲线加密/解密(基于《密码编码学与网络安全——原理与实践(第七版)》)

    [密码学Sage代码]椭圆曲线加密/解密(基于<密码编码学与网络安全--原理与实践(第七版)>) 教材内容: 实践的Sage代码: #[静水流深Sage代码]使用椭圆曲线密码体制进行加密/ ...

  3. 椭圆曲线加密和签名算法

    简述 椭圆曲线密码学,简称ECC.是一种建立公开加密的算法,也就是非对称加密.和RSA类似.被公认在给定密钥长度下最安全的加密算法.应用范围很广,主要的三个技术TLS.PGP.SSH都在使用它,特别是 ...

  4. 椭圆曲线加密概览(二)

    椭圆曲线配对是包括确定性阈值签名,zk-SNARK和其他更简单形式的零知识证明在内的各种构造背后的关键密码原语 椭圆曲线配对(或更确切地说,我们将在此处探讨的配对的具体形式:尽管其逻辑相当相似,也存在 ...

  5. Web技术(三):TLS 1.2/1.3 加密原理(AES-GCM + ECDHE-ECDSA/RSA)

    文章目录 前言 一.TLS 加密原理 1.1 TLS 信息加密 1.2 TLS 完整性校验与认证加密 1.3 TLS 报文结构 1.4 TLS 密钥交换 1.5 TLS 数字签名 1.6 TLS 密码 ...

  6. tls 1.2加密_椭圆曲线加密在TLS 1.3中的工作方式

    tls 1.2加密 A couple of reader alerts: 读者警告: In order to (somewhat) simplify the description process a ...

  7. python椭圆曲线加密算法_ECC椭圆曲线加密学习笔记

    0x00 前言 之前做题的时候遇到一个ECC相关的题目,学习了好几篇大佬的文章ECC的剖析文章,学习之后也记录一下,写一遍加强自己的巩固. 此文章严格意义上来讲应该算是读书笔记,在总结过程中观摩了很多 ...

  8. 密码学之RSA加密原理解析

      密码学是指研究信息加密,破解密码的技术科学.密码学的起源可追溯到2000年前.而当今的密码学是以数学为基础的.   密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截获情报, ...

  9. 椭圆曲线加密(Elliptic Curve Cryptography, ECC)

    近年来,国内外的科研人员面向设备资源受到限制的多种场景提出了很多基于ECC的认证密钥协商协议.虽然各协议应用场景不尽相同,但解决的问题和最终的目标都较为类似,可以归纳为在性能开销尽可能小的前提下,安全 ...

最新文章

  1. 建立实体-关系模型2
  2. [.net 面向对象编程基础] (13) 面向对象三大特性——多态
  3. java获取本周的开始时间和结束时间_2020年三伏天时间表什么时候开始结束 2020年三伏具体时间表一览...
  4. 更了吗?Windows 11 22000.184 推送
  5. vue value key
  6. 【Kafka】Failed to send data to Kafka: Failed to allocate memory within the configured max blocking
  7. oracle数据库创建用户
  8. C语言中指针的基类型,c – 将指针从一种基类型转换为另一种基类型
  9. thinkphp数据表操作恐怖事件。
  10. tensorflow python2迁移python3_tensorflow在python2和python3上的安装教程
  11. 百度分享代码_网销侠:网络营销百问百答之51,百度小程序是什么
  12. pytorch nonzero_[深度学习框架]PyTorch常用代码段
  13. visa虚拟卡生成器_虚拟信用卡。亲,你懂了吗?
  14. 服务器被攻击ip显示美国,大神:服务器疑是被攻击,netstat命令看到连接有很多国外IP...
  15. JS设计模式-单例模式
  16. scp远程传输文件之权限被拒绝解决方案
  17. html5水墨效果,html5 canvas水墨风格的云雾动画特效
  18. cut out数据增强_数据增强:Mixup,Cutout,CutMix | Mosaic
  19. BOM 物料清单 Bill Of Materials
  20. 【音视频工具】前端屏幕录制工具 + 录制<video>标签内容

热门文章

  1. 雷军以为会当一辈子码农,不料后来成了小米董事长
  2. IP数据报的检验(计算机网络)
  3. ipad如何分屏_基于ipad的生态型无纸化学习说明书
  4. UVALive 7279 Sheldon Numbers (暴力打表)
  5. 手机拍照技巧:全景拍摄,让手机拍出的照片妙趣横生
  6. react-native pod install: [!] Error installing boost-for-react-native
  7. 太秀了!那个在 GitHub 用文言文编程的小哥,竟从 28 万行唐诗中找出了对称矩阵...
  8. golang图片属性orientation在image.Decode后丢失,导致图片上传后旋转
  9. PI实时数据库接口技术的应用
  10. 条码标签设计软件Nicelabel使用方法