ECDSA数字签名
ECDSA算法(深入浅出密码学笔记)
ECDSA标准中的步骤与DSA方案的步骤在概念上紧密相连,但ECDSA中的离散对数问题是在椭圆曲线群中构建起来的。因此,实际计算一个ECDSA签名所执行的算术运算与DSA中的完全不同。
ECDSA标准是针对素数域Zp\mathbb{Z}_pZp和有限域GF(2m)GF(2^m)GF(2m)上的椭圆曲线定义的
密钥生成
- 使用椭圆曲线EEE,其中:模数为ppp;系数为aaa和bbb;生成素数阶qqq的循环群的点A
- 选择一个随机整数ddd,且0<d<q0<d<q0<d<q.
- 计算B=dAB=dAB=dA
密钥为:
kpub=(p,a,b,q,A,B)k_{pub}=(p,a,b,q,A,B)kpub=(p,a,b,q,A,B)
kpr=(d)k_{pr}=(d)kpr=(d)
注意:我们已经建立了一个离散对数问题,其中整数d为私钥,标量乘法的结果点B为公钥。与DSA一样,循环群的阶是q;而为了达到更高的安全等级,这个数的长度大小应该大于等于160位。
签名与验证
与DSA一样,ECDSAECDSAECDSA签名由一对整数(r,s)(r,s)(r,s)组成,其中每个值的位长度都与qqq相同,这也有助于实现十分简洁的签名。使用公钥和私钥计算消息xxx的签名的方式如下:
ECDSA签名生成
- 选择一个整数作为随机临时密钥kEk_EkE,且0<kE<q0<k_E<q0<kE<q。
- 计算R=kEAR=k_EAR=kEA。
- 设置r=xRr=x_Rr=xR。
- 设置s≡(h(x)+d⋅r)kE−1mod qs\equiv(h(x)+d\cdot r)k_E^{-1} \mod qs≡(h(x)+d⋅r)kE−1modq。
在步骤3中,点R的x坐标赋给变量r。在计算s时,必须使用函数h对消息x进行哈希。哈希函数的输出长度必须至少与q一样长。
ECDSA签名验证
- 计算辅助值w≡s−1mod qw\equiv s^{-1} \mod qw≡s−1modq。
- 计算辅助值u1≡w⋅h(x)mod qu_1\equiv w\cdot h(x) \mod qu1≡w⋅h(x)modq。
- 计算辅助值u2≡w⋅rmod qu_2\equiv w\cdot r \mod qu2≡w⋅rmodq。
- 计算P=u1A+u2BP=u_1A+u_2BP=u1A+u2B。
- 验证verkpub(x,(r,s))ver_{k_{pub}}(x,(r,s))verkpub(x,(r,s))为:
若xp≡rmod qx_p\equiv r \mod qxp≡rmodq则为有效签名;
若xp≢rmod qx_p \not\equiv r \mod qxp≡rmodq则为无效签名。
最后一步中的xpx_pxp表示点P的x坐标。只有当xpx_pxp与签名参数r模q相等时,验证者才会接受签名(r,s);否则,此签名将被看做时无效的。
证明就不放了,放个小例子吧
举例
首先,椭圆曲线为:E:y2≡x3+2x+2mod 17E:y^2\equiv x^3+2x+2 \mod 17E:y2≡x3+2x+2mod17
Bob选择p=17,a=2,b=2的曲线E和q=19的点A=(5,1)。选择d=7;计算B=dA=7⋅(5,1)=(0,6)Bob选择p=17,a=2,b=2的曲线E和q=19的点A=(5,1)。选择d=7;计算B=dA=7\cdot(5,1)=(0,6)Bob选择p=17,a=2,b=2的曲线E和q=19的点A=(5,1)。选择d=7;计算B=dA=7⋅(5,1)=(0,6)
Bob向Alice发送公钥(p,a,b,q,A,B)=(17,2,2,19,(5,1),(0,6))Bob向Alice发送公钥(p,a,b,q,A,B)=(17,2,2,19,(5,1),(0,6))Bob向Alice发送公钥(p,a,b,q,A,B)=(17,2,2,19,(5,1),(0,6))
签名:Bob计算消息h(x)=26的哈希值;选择临时密钥kE=10,R=10⋅(5,1)=(7,11),r=xR=7,s=(26+7⋅7)⋅2≡17mod 19签名:Bob计算消息h(x)=26的哈希值;选择临时密钥k_E=10,R=10\cdot (5,1)=(7,11),r=x_R=7,s=(26+7\cdot 7)\cdot 2\equiv 17 \mod 19签名:Bob计算消息h(x)=26的哈希值;选择临时密钥kE=10,R=10⋅(5,1)=(7,11),r=xR=7,s=(26+7⋅7)⋅2≡17mod19
发送签名:(x,(r,s))=(x,(7,17))发送签名:(x,(r,s))=(x,(7,17))发送签名:(x,(r,s))=(x,(7,17))
Alice方验证:Alice方验证:Alice方验证:
w=17−1≡9mod 19w=17^{-1}\equiv9 \mod 19w=17−1≡9mod19
u1=9⋅26=6mod 19u_1 =9\cdot 26=6 \mod 19u1=9⋅26=6mod19
u2=9⋅7≡6mod 19u_2=9\cdot7\equiv6\mod 19u2=9⋅7≡6mod19
P=6⋅(5,1)+6⋅(0,6)=(7,11)P=6\cdot(5,1)+6\cdot(0,6)=(7,11)P=6⋅(5,1)+6⋅(0,6)=(7,11)
xp≡rmod 19⇒有效的签名x_p\equiv r \mod 19\Rightarrow 有效的签名xp≡rmod19⇒有效的签名
Python实现
需要引入模块ecdsa
import ecdsa
选取一个椭圆曲线,这里以NIST256p为例
gen = ecdsa.NIST256p.generator
order = gen.order()
ecdsa模块中有封装好了的函数可以赋值直接生成ecdsa公钥,私钥的对象
# 生成私钥d_A
d_A = random.randrange(1,order-1)
# 生成公私钥对象
public_key = ecdsa.ecdsa.Public_key(gen,gen * d_A)
private_key = ecdsa.ecdsa.Private_key(public_key,d_A)
数字签名
message = "message"
m = int(hashlib.sha1(message.encode("utf8")).hexdigest(),16)
# 临时密钥
k = random.randrange(1,order-1)
# 签名
signature = private_key.sign(m,k)
r = signature.r
s = signature.s
更多推荐



所有评论(0)