为什么是椭圆曲线加密?
椭圆曲线加密(以下简称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,这个问题是大整数因子分解问题;对于离散对数加密,是离散对数问题;对于椭圆曲线加密,则是椭圆曲线上的离散对数问题。
本文主要介绍椭圆曲线加密,但是离散对数加密和椭圆曲线加密原理比较相似,在这里一起介绍。
离散对数问题
我们在中学里学的对数问题是指,
给定正实数 a a a和 a x a^x ax,求 x x x。也就是计算 x = log a a x x=\log_a{a^x} x=logaax。
这是实数域上的对数问题,不是什么难算的东西,随便按一下计算器结果就出来了。
而离散对数问题是指这样的问题:
给定素数 p p p和正整数 g g g,知道 g x m o d p g^x\mod p gxmodp的值,求 x x x
对于符合特定条件的 p p p和 g g g,这个问题是很难算的,更准确地说,是没有多项式时间的解法。而 g x m o d p g^x \mod p gxmodp的计算却非常快,由此造成了正向和逆向天差地别的计算速度。打个比方,就像随手一扔,玻璃杯就摔碎成渣,而想要将一堆玻璃渣拼回完整的玻璃杯,即使做得到,所需的人力物力也远远大于当初那随手一扔。
Diffie–Hellman密钥交换
Diffie–Hellman密钥交换(以下简称DH)是用于双方在可能被窃听环境下安全交换密钥的一种方法。
算法的安全性是由上面提到的离散对数难题保证。
具体算法流程如下:
- 小红和小明约定 p p p和 g g g的值
- 小红生成私钥 x x x,计算 g x m o d p g^x\mod p gxmodp作为公钥公布出去
- 小明生成私钥 y y y,计算 g y m o d p g^y\mod p gymodp作为公钥公布出去
- 小红得知 g y m o d p g^y\mod p gymodp后,计算
s = ( g y m o d p ) x m o d p = ( g y ) x m o d p = g x y m o d p s=(g^y\mod p)^x\mod p=(g^y)^x\mod p=g^{xy}\mod p s=(gymodp)xmodp=(gy)xmodp=gxymodp- 小明得到 g x m o d p g^x\mod p gxmodp后,计算
s = ( g x m o d p ) y m o d p = ( g x ) y m o d p = g x y m o d p s=(g^x\mod p)^y\mod p=(g^x)^y\mod p=g^{xy}\mod p s=(gxmod