尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

特殊的数字签名

特殊的数字签名
📅 发布时间:2026/6/20 19:01:05
特殊的数字签名盲签名 -- 部分盲签名 -- 群签名

盲签名

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...")

相关新闻

  • 102302136 林伟杰 数据采集与融合作业1
  • 极值定理
  • 10.25 CSP-S 模拟赛

最新新闻

  • 合肥理工学校 2026 招生什么条件?2026年6月21号最新公布! - 教育为先
  • 开发K8s准入控制器前的准备工作:集群检查与项目搭建指南
  • 做税务体检怕踩坑?广州中小企业服务筛选全攻略 - 资讯速览
  • STM32F103C8 + FreeRTOS + ESP32 学习记录(一):从零搭建联网天气时钟站(硬件篇)
  • 靠谱营业性演出许可证代办机构推荐 - 资讯速览
  • 想找好用的长沙全屋定制公司?这里给你揭晓答案! - 资讯速览

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号