Signature
题目是:
import ecdsaimport randomdef ecdsa_test(dA,k):sk = ecdsa.SigningKey.from_secret_exponent(secexp=dA,curve=ecdsa.SECP256k1)sig1 = sk.sign(data=b'Hi.', k=k).hex()sig2 = sk.sign(data=b'hello.', k=k).hex()#不同的kr1 = int(sig1[:64], 16)s1 = int(sig1[64:], 16)s2 = int(sig2[64:], 16)return r1,s1,s2if __name__ == '__main__':n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141a = random.randint(0,n)flag = 'flag{' + str(a) + "}"b = random.randint(0,n)print(ecdsa_test(a,b))# (4690192503304946823926998585663150874421527890534303129755098666293734606680, 111157363347893999914897601390136910031659525525419989250638426589503279490788, 74486305819584508240056247318325239805160339288252987178597122489325719901254)
分析代码可以看出,存在随机数重复使用。
具体来说,这段代码中签名的过程中使用了相同的随机数 k 来对不同的消息进行签名。
这种情况下,可以通过分析两个相同 k 值对应的消息签名来恢复私钥 dA。
import sympyfrom hashlib import sha1from Cryptodome.Util.number import long_to_bytes , bytes_to_longdef calculate_private_key(r1, s1, s2, h1, h2, n):# 计算k值k = ((h1 - h2) * sympy.mod_inverse(s1 - s2, n)) % n# 计算私钥dAdA = (sympy.mod_inverse(r1, n) * (k * s1 - h1)) % nreturn dAif __name__ == "__main__":# 定义椭圆曲线的参数n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141# 签名中的r1, s1, s2值r1 = 4690192503304946823926998585663150874421527890534303129755098666293734606680s1 = 111157363347893999914897601390136910031659525525419989250638426589503279490788s2 = 74486305819584508240056247318325239805160339288252987178597122489325719901254h1 = bytes_to_long(sha1(b'Hi.').digest())h2 = bytes_to_long(sha1(b'hello.').digest())private_key = calculate_private_key(r1, s1, s2, h1, h2, n)print(f'flag{{{private_key}}}')---------------------------------------------------------flag{40355055231406097504270940121798355439363616832290875140843417522164091270174}
椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm,ECDSA)是一种基于椭圆曲线密码学的数字签名算法。它广泛应用于需要确保数据完整性和身份验证的场景中,例如在区块链技术(如比特币)、安全通信协议(如TLS/SSL)等领域。
-
基本原理
ECDSA 是一种非对称加密算法,它基于椭圆曲线数学的复杂性来实现数字签名的生成和验证。其核心思想是利用椭圆曲线上的点的加法运算和标量乘法运算,这些运算在数学上是单向的,即很容易进行正向计算,但很难进行逆向求解。
-
椭圆曲线:椭圆曲线是一种特殊的数学曲线。椭圆曲线上的点具有特殊的代数结构,使得点的加法和标量乘法运算可以高效地实现。
-
私钥和公钥:在 ECDSA 中,私钥是一个随机生成的大整数 d,公钥是椭圆曲线上的一个点 Q,通过 Q=d×G 计算得到,其中 G是椭圆曲线上的一个基点。
-
签名生成过程
签名生成过程主要包括以下步骤:
-
选择随机数:签名者选择一个随机整数 k(称为临时私钥),并计算椭圆曲线上的点 R=k×G。
-
计算 r 和 s:
-
r 是点 R 的 x 坐标对模数 n(椭圆曲线的阶)取模的结果。
-
s=k−1(H(m)+d⋅r)mod n,其中 H(m) 是消息 m 的哈希值,k−1 是 k 的模逆元。
-
-
输出签名:签名由 (r,s) 组成。
-
签名验证过程
验证签名的过程主要包括以下步骤:
-
计算 w:验证者计算 w=s−1mod n。
-
计算 u1 和 u2:
-
u1=H(m)⋅w mod n
-
u2=r⋅w mod n
-
-
计算点 R′:计算 R′=u1×G+u2×Q。
-
验证 r:检查 r 是否等于 R′ 的 x 坐标对模数 n 取模的结果。如果相等,则签名验证通过,否则验证失败。