当前位置: 首页 > article >正文

Signature

Signature

题目是:

 import ecdsa
 import random
 ​
 def 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()
                                                 #不同的k
     r1 = int(sig1[:64], 16)
     s1 = int(sig1[64:], 16)
     s2 = int(sig2[64:], 16)
     return r1,s1,s2
 ​
 if __name__ == '__main__':
     n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
     a = 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 sympy
 from hashlib import sha1
 from Cryptodome.Util.number import long_to_bytes , bytes_to_long
 ​
 def calculate_private_key(r1, s1, s2, h1, h2, n):
     # 计算k值
     k = ((h1 - h2) * sympy.mod_inverse(s1 - s2, n)) % n
     # 计算私钥dA
     dA = (sympy.mod_inverse(r1, n) * (k * s1 - h1)) % n
     return dA
  
 if __name__ == "__main__":
     # 定义椭圆曲线的参数
     n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
     # 签名中的r1, s1, s2值
     r1 = 4690192503304946823926998585663150874421527890534303129755098666293734606680
     s1 = 111157363347893999914897601390136910031659525525419989250638426589503279490788
     s2 = 74486305819584508240056247318325239805160339288252987178597122489325719901254
     h1 = 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)等领域。

  1. 基本原理

ECDSA 是一种非对称加密算法,它基于椭圆曲线数学的复杂性来实现数字签名的生成和验证。其核心思想是利用椭圆曲线上的点的加法运算和标量乘法运算,这些运算在数学上是单向的,即很容易进行正向计算,但很难进行逆向求解。

  • 椭圆曲线:椭圆曲线是一种特殊的数学曲线。椭圆曲线上的点具有特殊的代数结构,使得点的加法和标量乘法运算可以高效地实现。

  • 私钥和公钥:在 ECDSA 中,私钥是一个随机生成的大整数 d,公钥是椭圆曲线上的一个点 Q,通过 Q=d×G 计算得到,其中 G是椭圆曲线上的一个基点。

  1. 签名生成过程

签名生成过程主要包括以下步骤:

  1. 选择随机数:签名者选择一个随机整数 k(称为临时私钥),并计算椭圆曲线上的点 R=k×G。

  2. 计算 r 和 s

    • r 是点 R 的 x 坐标对模数 n(椭圆曲线的阶)取模的结果。

    • s=k−1(H(m)+d⋅r)mod n,其中 H(m) 是消息 m 的哈希值,k−1 是 k 的模逆元。

  3. 输出签名:签名由 (r,s) 组成。

  1. 签名验证过程

验证签名的过程主要包括以下步骤:

  1. 计算 w:验证者计算 w=s−1mod n。

  2. 计算 u1 和 u2

    • u1=H(m)⋅w mod n

    • u2=r⋅w mod n

  3. 计算点 R′:计算 R′=u1×G+u2×Q。

  4. 验证 r:检查 r 是否等于 R′ 的 x 坐标对模数 n 取模的结果。如果相等,则签名验证通过,否则验证失败。


http://www.kler.cn/a/529014.html

相关文章:

  • 数据结构(栈结构之顺序栈操作实现一)
  • C++ 字母大小写转换两种方法统计数字字符的个数
  • 【股票数据API接口47】如何获取股票指历史分时KDJ数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • 远程连接-简化登录
  • 进程控制-前篇
  • OpenCV:SURF、OBR特征检测
  • IS-IS 数据包类型 | 实验
  • TCL C++开发面试题及参考答案
  • Docker容器数据恢复
  • 【实战篇章】深入探讨:服务器如何响应前端请求及后端如何查看前端提交的数据
  • Autogen_core源码:_cache_store.py
  • C# 类与对象详解
  • 1.4第1章DC/DC变换器的动态建模-1.4状态空间平均法--电力电子系统建模及控制 (徐德鸿)--读书笔记
  • [NOIP1997 普及组] 棋盘问题
  • 一、TensorFlow的建模流程
  • 受限玻尔兹曼机:原理、实现、与神经网络对比及应用
  • 从理论到实践:Linux 进程替换与 exec 系列函数
  • 29.Word:公司本财年的年度报告【13】
  • 嵌入式C语言:大小端详解
  • 2.1.3 相机图像信号处理的基本流程