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

特殊的数字签名

盲签名

Chaum盲签名协议

协议流程:

\[\begin{flalign} &Setup:\\ &\quad p,q = getPrime(safe.bit\_length);n = p * q;Pubkey = (n, e);Pravitekey = d\\ &Sign:\\ &\quad 盲化:USER\ choose\ k \in R[1,n - 1],compute\ m'\equiv m\cdot k^e(mod\ n),m'\rightarrow Signer\\ &\quad 签名:Signer\ compute\ s'\equiv (m')^d(mod\ n),s'\rightarrow USER\\ &\quad 去盲;USER\ compute\ s \equiv k^{-1}\cdot s'(mod\ n),(m,s)\rightarrow Verifier\\ &Verify:\\ &\quad return\quad s^e(mod \ n) == m& \end{flalign} \]

The attack I attempted on an impulse

  • 阅读教材时发现,在选举系统中,投票结束后会公开(m,s),本人最初认为如果公开(m,s)就不再满足防追踪性(不可关联性)。具体攻击(后续也证明这种思路是不可行的)思路如下:

\[\begin{flalign} &Target:选定一组(m',s'),若寻找到该(m',s')所对应的(m,s)则攻击成功.\\ &\quad 设公开的所有选民的(m,s)为(m,s)group.由m_i'\equiv m_i \cdot k_i^e(mod\ n);s_i'\equiv m_i^d\cdot k_i(mod\ n);s_i\equiv m_i^d(mod\ n)\rightarrow k_i\equiv s_i'\cdot s_i^{-1}(mod\ n)\\ &Attack:\\ &设选定(m_j',s_j')\\ &\quad for\ i \ in\ 1..num\\ &\quad\quad k' \equiv s_j' \cdot s_i^{-1}(mod\ n)\\ &\quad\quad if\ m_i\cdot (k_i')^e(mod\ n) \equiv m_j'\\ &\quad\quad\quad j\ is\ i\\ &攻击思路:由(m,s)group我们可以根据s与s'的关系,计算一个kgroup。\\ &针对于选定的(m',s'),只有与之对应的(m,s)计算的k_{temp}与当初USER选定的盲化因子相同,但其一定存在于我们计算的kgroup.\\ &事实正确确实如此,但是理想协议执行状态下Signer不可获取所有USER的k,因此,我尝试采用m'==m\cdot k_{guess}^e(mod\ n)来判定.\\ &但是结果并没有达到Target.原因如下:\\ &\quad k_{guessi}\equiv s_j'\cdot s_i^{-1}(mod\ n)\rightarrow m_i\cdot k_{guessi}^e(mod\ n)\equiv m_i\cdot (s_j')^e \cdot s_i^{-e}(mod\ n)\equiv m_i\cdot (m_j^d\cdot k_j)^e\cdot m_i^{-1}\equiv m_j\cdot k_j^e(mod\ n)\equiv m'\\ &故m_i\cdot k_{guessi}^e\equiv m'恒成立,攻击失效. \end{flalign} \]

from Crypto.Util.number import getPrime, inverse
import random###################### 初始化阶段 ######################
p = getPrime(512); q = getPrime(512)
n = p * q
e = 65537 # RSA加密常用公钥指数
phi = (p - 1) * (q - 1); d  = inverse(e, phi)###################### 预处理 ######################
# 设有100名人员参与投票
x = 100
# k_list为每位选票人员盲化时生成的随机数k, k ∈ [1, n - 1]
k_list = [random.randrange(1, n) for _ in range(x)]
# m_list为每为选票人员所投出去的票,为验证结果情况,取值为 1..100
m_list = [i for i in range(1, x + 1)]###################### 签名阶段 ######################
# ss_list 存储选举委员会签名后的 s'; s_list存储最终提交的验证结果; mm_list存储盲化后的 m'
# 至此,我们有了 (m_list, s_list) 与 (mm_list, ss_list),前者对应教材公开后的(m, s); 后者对应选举委员会进行签名时收到的结果
# k_list并非 kgroup; 设 kk_list 表示公开(m,s)后委员会计算的 kgroup
ss_list = []; s_list = []; mm_list = []
for i in range(x):m = m_list[i]; k = k_list[i]# 盲化 mm 代替协议中的 m'mm = m * pow(k, e, n) % n # m' = m * k ^ e (mod n)ss = pow(mm, d, n) # s' = m' ^ d (mod n)s = ss * inverse(k, n) % nmm_list.append(mm); ss_list.append(ss); s_list.append(s)
###################### 验签阶段 ######################
# 若结果为 False ,输出 "Error" 后退出验证
for i in range(x):m = m_list[i]; s = s_list[i]if pow(s, e, n) != m:print("Error")break
###################### 攻击阶段 ######################
print("Attack begin.")
# 我们选取第 51 组的 (m', s'),找到其对应的(m, s)即攻击成功,即若后续结果校验时,在 i = 51 处显示正确,则说明攻击成功
mm = mm_list[51]; ss = ss_list[51]
# 1. 计算 kgroup
kk_list = []
for i in range(x):s = s_list[i]k_guess = ss * inverse(s, n) % n # k_guess = s' * s ^ {-1} (mod n)kk_list.append(k_guess)
# 2. 令 m'' = m * k_guess ^ e (mod n) ,采用 m'' == m' 进行校验
for i in range(x):m = m_list[i]k = kk_list[i]# mmm 表示当前计算的  m'', mm = m * k ^ e (mod n)mmm = m * pow(k, e, n) % nif mmm == mm:print(f"The origin of (m', s') is {i}")
print("Attack over.")

Code

from Crypto.Util.number import getPrime, bytes_to_long
import randomclass TA:def __init__(self):self.p, self.q = [getPrime(1024) for _ in range(2)]self.n = self.p * self.qself.e = 65537phi = (self.p - 1) * (self.q - 1)self.d = pow(self.e, -1, phi)class USER:def __init__(self, TA):self.TA = TAself.k = random.randrange(1, self.TA.n)def blinding(self, message):if isinstance(message, bytes):message = bytes_to_long(message)mm = message * pow(self.k, self.TA.e, self.TA.n) % self.TA.nreturn mmdef unblinding(self, ss):return pow(self.k, -1, self.TA.n) * ssclass Signer:def __init__(self, TA):self.TA = TAdef sign(self, mm):return pow(mm, self.TA.d, self.TA.n)class Verifier:def __init__(self, TA):self.TA = TAdef verify(self, mspair:tuple) -> bool:m, s = mspairif isinstance(message, bytes):m = bytes_to_long(m)return m == pow(s, self.TA.e, self.TA.n)   
if __name__ == "__main__":ta = TA()user = USER(ta)signer = Signer(ta)verifier = Verifier(ta)message = b'I choose Alice to go.'mm = user.blinding(message)ss = signer.sign(mm)s = user.unblinding(ss)flag = verifier.verify((message, s))if flag:print("Verify Successfully.")else:print("Error...")
http://www.fuzeviewer.com/news/412/

相关文章:

  • 【CI130x 离在线】如何运行 curl 脚本
  • 这才是真正的AI NAS!极空间私有云Z2Ultra评测
  • 新东方第三节课名言作文
  • 十月阅读_3
  • 中考_体育
  • 常见问题处理 --- phpstudy启动mysql失败
  • 20232308 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 【密码学实战】openHiTLS PKCS12命令行程序: PKCS12文件生成与解析
  • 「CTSC2017-游戏」题解
  • vue3 vue3-form-element表单生成工具 输入框增加后缀
  • 20232402 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 掘金2025年:数字化商业浪潮下,如何选对平台与伙伴?一站式多商户商城系统推荐榜发布,多商户商城代理招募/多商户项目合伙人加盟/一站式开店代理项目加盟
  • 为医疗器械行业搭建“数字桥梁”,破解协同效率与合规难题
  • PostgreSQL 服务版
  • 20232307 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 2025年10月办公家具公司评价榜:基于真实数据的权威推荐清单
  • vue+antv/x6项目使用问题
  • 《程序员修炼之道:从小工到专家》前五分之一观后感
  • 坐标系与投影关系
  • 用gdb的动态视角看ret2text的实现
  • 1027随笔
  • ask_skill
  • SVN 主分支合并之通过主分支合并子分支执行流程
  • 现代c++编程体验2
  • 化繁为简:解密国标GB28181算法算力平台EasyGBS如何以兼容性与易用性赋能安防集成
  • 计算机毕业设计springboot音乐畅听系统 基于Spring Boot框架的智能音乐播放系统编写 Spring Boot驱动的音乐在线欣赏平台构建
  • vue2 封装组件使用 v-mode【el-radio,el-input】
  • P11993 [JOIST 2025] 迁移计划 题解
  • ERP和CRM、SRM、MES之间的关系,怎么理解?
  • 2025年市面上氟碳铝单板品牌、市场氟碳铝单板公司、国内氟碳铝单板生产厂家、2025年氟碳铝单板品牌、口碑好的氟碳铝单板产品综合评测