一、概述
如今许多加密算法和安全标准都会使用公钥算法来加解密、数字签名。其中RSA为最广泛使用的算法。RSA算法基于离散对数问题,密钥长度越长安全性越高。近年来,出于安全需求,RSA的密钥长度变得越来越长,运算时间也越来越慢。在交易任务数量庞大的今天,长时间的密码学运算给系统造成不小的负担。因此,拥有更小密钥长度的椭圆曲线算法正充当着越来越重要的角色。研究表明,同等安全性条件下,使用256位的椭圆曲线密钥与使用3072位RSA密钥的安全性相当。
二、原理
2.1 椭圆曲线
椭圆曲线跟我们高中学的椭圆不同,它是一个有限域上的平面曲线,曲线上的点满足方程
y
2
=
x
3
+
a
x
+
b
y^2=x^3+ax+b
y2=x3+ax+b
对于椭圆曲线域以及曲线上的操作满足阿贝尔群的定义,关于阿贝尔群可以参考我之前的博客
椭圆曲线与阿贝尔群的对应关系如下:
- 首先是运算的对象,在椭圆曲线上一般为点。
- 然后是运算的符号,阿贝尔群中的
+
+
+ 在椭圆曲线中定义如下
R + Q + P ′ = 0 R+Q+P' = 0 R+Q+P′=0
R + Q = − P ′ = P R+Q = -P' = P R+Q=−P′=P
简单来说就是R点加Q点,等于RQ所在直线与椭圆曲线的交点,对x轴作对称的点
- 最后是运算的幺元为无穷远点 O O O ,因为其满足 O = − O O = -O O=−O 且 P + O = P = O + P P+O = P = O+P P+O=P=O+P
当R和Q重合时,RQ所在的直线为椭圆曲线的切线,此时,我们可以用数字点乘的形式代表
Q
+
Q
=
2
Q
Q+Q=2Q
Q+Q=2Q
对于 数字乘点 这个运算,符合乘法交换律,如下例:
2
(
3
Q
)
=
3
(
2
Q
)
=
6
Q
2(3Q)=3(2Q)=6Q
2(3Q)=3(2Q)=6Q
对于一个数字乘点操作,已知点 Q Q Q 和数字 k k k ,我们可以很轻松算出点 P = k Q P=kQ P=kQ ,但是已知 P P P 和 Q Q Q 的情况下,算出 k k k 往往是很复杂的,就像在一个四面都是镜面,封闭的房间中,有一束激光光源和反射点,我们无法推测该光源究竟经过了多少次反射才能映射到反射点。这就是椭圆曲线加密中使用到的最核心的特性。在公钥加密算法中, Q Q Q点常作为一个公开的基点, k k k点为私钥,通常为随机数, P = k Q P=kQ P=kQ 则常被用作公钥。
下面贴一份蛋老师的讲解视频,讲得很清楚,可以作为博客的补充。
2.2 Elliptic Curve Diffie-Hellman算法(ECDH)
Diffie-Hellman是一种密钥交换算法,可以在一个非安全的通信渠道中形成一个共享、不会被窃取的密文。刚刚分享的视频里也举了个例子,假设Alice的私钥是蓝色,Bob的私钥是红色,公钥是黄色,他们想生成一个共享的颜色,但是又不想其他人知道这个颜色,于是他们首先用自己的私钥颜色和公钥颜色混合,然后将该混合颜色发送给对方,如Alice将蓝色和黄色混合得到绿色,Bob将黄色和红色混合得到褐色,然后Alice把绿色发给Bob,Bob将褐色发给Alice,然后他们再使用这个颜色和自己的颜色混合,得到相同的黄褐色。
蓝
+
黄
+
红
=
红
+
黄
+
蓝
蓝+黄+红 = 红+黄+蓝
蓝+黄+红=红+黄+蓝
在ECDH算法中,相同的场景,Alice和Bob想生成一个共同的密文,Alice拥有密钥对
(
d
A
,
Q
A
)
(d_A,Q_A)
(dA,QA),Bob拥有密钥对
(
d
B
,
Q
B
)
(d_B,Q_B)
(dB,QB)。Alice和Bob相互知道对方的
Q
Q
Q。下一步,Alice会计算
(
x
k
,
y
k
)
=
d
A
Q
B
(x_k,y_k)=d_A Q_B
(xk,yk)=dAQB,Bob会计算
(
x
k
,
y
k
)
=
d
B
Q
A
(x_k,y_k)=d_B Q_A
(xk,yk)=dBQA ,共享的密文为
x
k
x_k
xk。因为
d
A
Q
B
=
d
A
(
d
B
G
)
=
d
B
(
d
A
G
)
=
d
B
Q
A
d_AQ_B=d_A(d_BG)=d_B(d_AG)=d_BQ_A
dAQB=dA(dBG)=dB(dAG)=dBQA
在ECDH中,Alice和Bob对外界都只展示公钥 Q Q Q ,没有人能够从公钥算出私钥,所以攻击者也无法得到共享密文 x k = d Q x_k=dQ xk=dQ 了。而且为了进一步保护信息,通常共享密文会经过hash处理,去除密文中的weak bits使得攻击更加困难。
2.3 Elliptic Curve Digital Signature Algorithm算法(ECDSA)
椭圆曲线的特性同样能被利用在数字签名算法中,它是DSA算法中的一个变种。
这里列出具体的符号定义
Parameter | |
---|---|
Ep(a,b) | 椭圆曲线,方程为 y 2 = x 3 + a x + b y^2=x^3+ax+b y2=x3+ax+b |
G G G | 基点,一个曲线上的大素数阶n子群的点 |
n n n | G的阶,满足 n G = O nG=O nG=O, O O O是幺元 |
d A d_A dA | 私钥,一个随机数 |
Q A Q_A QA | 公钥, d A G d_AG dAG |
m m m | 发送出去的消息 |
H H H | 哈希处理后的消息 H a s h ( m ) Hash(m) Hash(m) |
数字签名具体流程如下,首先Alice和Bob回协商好通信的参数:
Alice:
- 选择一个椭圆曲线 E p ( a , b ) E_p(a,b) Ep(a,b),选择曲线上的一点 G G G作为基点。
- 生成公私钥对
(
Q
A
,
d
A
)
(Q_A,d_A)
(QA,dA),并将
n
n
n,
E
p
E_p
Ep,
G
G
G,
Q
A
Q_A
QA发送给Bob。
Bob: - 检查 Q A Q_A QA 是否不等于幺元 O O O。若等于,签名一定不合法
- 检查 Q A Q_A QA 是否在曲线 E p ( a , b ) E_p(a,b) Ep(a,b) 上
- 检查 n Q A nQ_A nQA 是否等于幺元 O O O
每次发送消息时:
Alice准备对消息
m
m
m 签名发送给Bob:
- Alice对消息作哈希 H = H a s h ( m ) H=Hash(m) H=Hash(m) ,哈希函数有SHA-2,SHA-3等,会把消息转换为一个整数
- 取 H H H最左的 n n n 个数字,得到消息摘要 z z z
- 选择一个介于 [ 1 , n − 1 ] [1,n-1] [1,n−1] 的随机数字 k k k
- 计算曲线上的点 R = ( x 1 , y 1 ) = k G R=(x_1,y_1)=kG R=(x1,y1)=kG
- 计算 r 1 = x 1 m o d n r_1=x_1 \mod n r1=x1modn,如果 r 1 = 0 r_1=0 r1=0,返回第3步
- 计算 s = k − 1 ( z + r d A ) m o d n s=k^{-1}(z+rd_A) \mod n s=k−1(z+rdA)modn,如果 s = 0 s=0 s=0,返回第3步,这里的 k − 1 k^{-1} k−1是模逆运算
- 得到签名 ( r , s ) (r,s) (r,s),值得注意的是, ( r , − s ) (r,-s) (r,−s) 也是一个合法的签名,在某些算法中,会把签名定义为 ( r , s , v ) (r,s,v) (r,s,v), v v v用于定义 s s s 究竟是哪一种情况。
Bob收到Alice的签名 ( r , s ) (r,s) (r,s) 和消息 m m m 后:
- 检查 r r r和 s s s是否在 [ 1 , n − 1 ] [1,n-1] [1,n−1]之间
- 计算消息的哈希 H H H 以及消息摘要 z z z
- 令 u 1 = z s − 1 m o d n u_1=zs^{-1}\mod n u1=zs−1modn, u 2 = r s − 1 m o d n u_2=rs^{-1}\mod n u2=rs−1modn
- 计算点 R ′ = ( x 1 , y 1 ) = u 1 G + u 2 Q A R'=(x_1,y_1)=u_1G+u_2Q_A R′=(x1,y1)=u1G+u2QA,如果 R ′ = O R'=O R′=O 签名不合法
- 如果 r ≡ x 1 ( m o d n ) r\equiv x_1(\mod n) r≡x1(modn),签名合法,否则不合法
原理:
R
′
=
u
1
G
+
u
2
Q
A
=
u
1
G
+
u
2
d
A
G
=
(
z
s
−
1
+
r
d
A
s
−
1
)
G
=
(
z
+
r
d
A
)
s
−
1
G
=
(
z
+
r
d
A
)
(
z
+
r
d
A
)
−
1
(
k
−
1
)
−
1
G
=
k
G
R
=
k
G
\begin{align*}R' &= u_{1} G+u_{2} Q_{A}\\&=u_{1} G+u_{2}d_{A} G\\&=(zs^{-1}+rd_{A}s^{-1}) G\\&=(z+rd_{A})s^{-1} G\\&=(z+rd_{A})(z+rd_{A})^{-1}(k^{-1})^{-1}G\\&=kG \\ R&=kG\end{align*} \\
R′R=u1G+u2QA=u1G+u2dAG=(zs−1+rdAs−1)G=(z+rdA)s−1G=(z+rdA)(z+rdA)−1(k−1)−1G=kG=kG
公钥恢复
Bob通过消息 m m m 和 Alice的签名 ( r , s ) (r,s) (r,s),Bob能恢复Alice的公钥 Q A Q_A QA
- 计算曲线上的一点 R = ( x 1 , y 1 ) R=(x_1,y_1) R=(x1,y1),其中 x 1 x_1 x1 是 r , r + n , r + 2 n … r,r+n,r+2n \dots r,r+n,r+2n… 中的数字。
- 令 u 1 = − z r − 1 m o d n u_1=-zr^{-1}\mod n u1=−zr−1modn, u 2 = s r − 1 m o d n u_2=sr^{-1}\mod n u2=sr−1modn
- 计算点 Q = ( x 1 , y 1 ) = u 1 G + u 2 R Q=(x_1,y_1)=u_1G+u_2R Q=(x1,y1)=u1G+u2R
- Q Q Q 为Alice公钥 Q A Q_A QA 的可能解。
原理:
Q
=
u
1
G
+
u
2
R
=
u
1
G
+
u
2
k
G
=
(
−
z
r
−
1
+
s
k
r
−
1
)
G
=
(
−
z
r
−
1
+
k
−
1
(
z
+
r
d
A
)
k
r
−
1
)
G
=
(
−
z
r
−
1
+
(
z
r
−
1
+
d
A
)
)
G
=
d
A
G
Q
A
=
d
A
G
\begin{align*}Q &= u_{1} G+u_{2} R\\&=u_{1} G+u_{2}kG\\&=(-zr^{-1}+skr^{-1}) G\\&=(-zr^{-1}+k^{-1}(z+rd_A)kr^{-1}) G\\&=(-zr^{-1}+(zr^{-1}+d_A))G\\&=d_AG \\ Q_A&=d_AG\end{align*} \\
QQA=u1G+u2R=u1G+u2kG=(−zr−1+skr−1)G=(−zr−1+k−1(z+rdA)kr−1)G=(−zr−1+(zr−1+dA))G=dAG=dAG
三、例子
下面的这台机器包括如下多曲线,每一条曲线都有清晰的名称。
这里给出一些曲线的具体参数
- secp256k1
- a = 0
- b = 7
- G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
- n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
- 国密SM2
- p = FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
- a = FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
- b = 28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
- n = FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF409 39D54123
- Gx = 32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589 334C74C7
- Gy = BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
- Curve25519
- a = 486662
- b = 1
- n = 2 252 + 27742317777372353535851937790883648493 2^{252}+27742317777372353535851937790883648493 2252+27742317777372353535851937790883648493
- Gx = 9