Python 利用PYQT5设计基于RSA算法盲签名的匿名化电子支付系统设计与实现

基于RSA算法的盲签名算法

        David Chaum 于1982年提出盲签名的概念,并利用RSA算法设计了第一个盲签名方案. 该方案的安全性基于大整数分解问题

盲签名的步骤

1.密钥生成

签名者执行以下步骤生成密钥对:

①签名者选择两个大素数p,q, 计算n=pq, φ(n)=(p-1)(q-1);

②签名者选择两个大整数e,d, 满足ed =1 mod φ(n), gcd(e, φ(n))= 1;

③签名者保存私钥(d,n), 并公开公钥(e, n)和安全哈希函数H:{0,1}*→Zn*.

2.盲化

①用户选择随机数r∈R Zn*, 计算m' = re H(m) mod n,其中m是待签名的消息;

②用户将盲化的消息m'发送给签名者.

 3.签名

签名者计算σ' ≡ m' d  mod n ,并将 σ' 发送给用户。

4.去盲化

用户计算σ ≡ σ' r-1  mod n

r-1是盲化因子的逆元

 5.签名正确性验证

用户通过验证σe ≡ H(m) mod n

详细设计

我们为这个基于盲签名的匿名化电子支付系统设计了服务端(交易方)和用户端(被交易方)。和一个管理系统

1.密钥生成

        使用RSA模块的generate生成密钥对

# 生成 RSA 密钥对
def generate_rsa_key_pair():private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)public_key = private_key.public_key()return private_key, public_key

2.生成盲化因子

        使用secrets.randbits(1024)生成一个1024位的随机数,再用Miller-Rabin算法检查n是否是素数当n为素数的时候输出为盲化因子

def generate_blinding_factor():# 生成盲化因子(一个1024位的随机素数)while True:prime_candidate = secrets.randbits(1024)if is_prime(prime_candidate):return prime_candidatedef is_prime(n, k=5):# 用Miller-Rabin算法检查n是否是素数if n < 2: return Falsefor p in [2,3,5,7,11,13,17,19,23,29]:if n % p == 0: return n == ps, d = 0, n - 1while d % 2 == 0:s, d = s + 1, d // 2for i in range(k):x = pow(secrets.randbelow(n-3) + 2, d, n)if x == 1 or x == n - 1: continuefor r in range(s - 1):x = pow(x, 2, n)if x == n - 1: breakelse:return Falsereturn True

3.消息盲化

        发送者使用盲化因子 k 对原始消息 m 进行盲化操作,生成盲化后的消息 m'。公钥 e 和 n 是接收者的公钥,在进行盲化和解盲化操作时需要使用。m‘=mk^emod(n)

def blind_hide_msg(msg, factor, e, n):hide_msg = (msg * pow(factor, e, n)) % nreturn hide_msg

4.接收方签名

接收方计算s’=(m’)^d(mod n)并把计算后的签名值s’发送给发送方

def blind_signature(blind_msg, d, n):blind_sig = pow(blind_msg, d, n)return blind_sig

5.解盲

        签名者将签名值 s' 发送回给发送者。发送者使用盲化因子的逆元素和签名值 s1 结合起来计算原始消息 m 的数字签名 s。

def blind_retrieve_sig(blind_sig, factor, n):inverse = pow(factor, -1, n)signature = (blind_sig * inverse) % nreturn signature

6.验证盲签名 

         发送方计算接收方发送的s‘,并计算出原始的消息m的数字签名 s=s’k^−1(mod n) 与接收方计算的数字签名进行一个比较,如果相同接收方验证盲签名成功! 用户通过验证s‘e ≡ H(m) mod n来验证盲签名

verification_result = pow(unblinded_signature2,e1,n1)

算法运行截图

完整算法代码

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
import binascii
import secrets
import gmpy2
import hashlib
import random
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Cryptodome.Util.number import inversedef blind_hide_msg(msg, factor, e, n):hide_msg = (msg * pow(factor, e, n)) % nreturn hide_msgdef blind_signature(blind_msg, d, n):blind_sig = pow(blind_msg, d, n)return blind_sig# 判断是否为素数
def is_prime(num):if num <= 1:return Falsefor i in range(2, int(num**0.5) + 1):if num % i == 0:return Falsereturn Truedef generate_blinding_factor():# 生成盲化因子(一个1024位的随机素数)while True:prime_candidate = secrets.randbits(1024)if is_prime(prime_candidate):return prime_candidatedef is_prime(n, k=5):# 用Miller-Rabin算法检查n是否是素数if n < 2: return Falsefor p in [2,3,5,7,11,13,17,19,23,29]:if n % p == 0: return n == ps, d = 0, n - 1while d % 2 == 0:s, d = s + 1, d // 2for i in range(k):x = pow(secrets.randbelow(n-3) + 2, d, n)if x == 1 or x == n - 1: continuefor r in range(s - 1):x = pow(x, 2, n)if x == n - 1: breakelse:return Falsereturn True# 生成 RSA 密钥对
def generate_rsa_key_pair():private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)public_key = private_key.public_key()return private_key, public_key# 保存密钥到文件
def save_key_to_file(key, filename):pem = key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.PKCS8,encryption_algorithm=serialization.NoEncryption())with open(filename, 'wb') as f:f.write(pem)# 从文件中加载密钥
def load_key_from_file(filename):with open(filename, 'rb') as f:pem = f.read()key = serialization.load_pem_private_key(pem, password=None)return keydef blind_retrieve_sig(blind_sig, factor, n):inverse = pow(factor, -1, n)signature = (blind_sig * inverse) % nreturn signature#--------------`--------------------------------------------------------------------------------
# 生成 RSA 密钥对
private_key, public_key = generate_rsa_key_pair()
bank_private_key, bank_public_key = generate_rsa_key_pair()# 保存私钥到文件
private_key_file = "private_key.pem"
private_key_file2 = "bank_private_key.pem"
save_key_to_file(private_key, private_key_file)
save_key_to_file(bank_private_key,private_key_file2)
# 保存公钥到文件
public_key_file = "public_key.pem"
public_key_file2 = "bank_public_key.pem"
with open(public_key_file, 'wb') as f:f.write(public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo))
with open(public_key_file2, 'wb') as f:f.write(public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo))# 从文件中加载密钥
loaded_private_key = load_key_from_file(private_key_file)
loaded_bank_private_key = load_key_from_file(private_key_file2)
loaded_public_key = serialization.load_pem_public_key(open(public_key_file, 'rb').read())
loaded_bank_public_key = serialization.load_pem_public_key(open(public_key_file2, 'rb').read())# 从加载的密钥中提取模数 n、私钥指数 d 和公钥指数 e
n = loaded_private_key.private_numbers().public_numbers.n
d = loaded_private_key.private_numbers().d
e = loaded_public_key.public_numbers().e# 从加载的密钥中提取模数 n、私钥指数 d 和公钥指数 e
n1 = loaded_bank_private_key.private_numbers().public_numbers.n
d1 = loaded_bank_private_key.private_numbers().d
e1 = loaded_bank_public_key.public_numbers().e# 清除返回值对象,防止泄露信息
loaded_private_key = None
loaded_public_key = Noneprint("n:", n)
print("d:", d)
print("e:", e)
print("n1:", n1)
print("d1:", d1)
print("e1:", e1)m =1234
# 生成盲化因子Alice选择一个随机数  k 作为盲化因子
k = generate_blinding_factor()
print("blinding factor",k)#generate_blinding_factor()函数使用secrets.randbits(1024)生成一个随机的1024位素数作为盲化因子。
#is_prime()函数使用Miller-Rabin算法检查整数是否是素数。然后,blind_message()函数将盲化因子应用于消息,以生成盲化的消息和盲化因子的值。
#1.发送者使用盲化因子 k 对原始消息 m 进行盲化操作,生成盲化后的消息 m'。公钥 e 和 n 是接收者的公钥,在进行盲化和解盲化操作时需要使用。
m1 = blind_hide_msg(m,k, e1, n1)#盲化
print("盲化后的消息 m':",m1)
#发送者将盲化后的消息 m1 发送给签名者。#2.签名者使用私钥对盲化后的消息 m1 进行解密操作,生成签名值 s1。 d1和n1是签名者银行的私钥
s1 = blind_signature(m1, d1, n1)
print("签名值 s'", s1)
real_sig = pow(m, d1, n1)
print("原签名 =", real_sig)#3.签名者将签名值 s' 发送回给发送者。发送者使用盲化因子的逆元素和签名值 s1 结合起来计算原始消息 m 的数字签名 s。
unblinded_signature2=blind_retrieve_sig(s1,k, n1)
print("解盲后", unblinded_signature2)if unblinded_signature2==real_sig:print("验证成功!!!!")
else:print("验证失败")hash_value = hashlib.sha256(str(m).encode()).digest()
# 4验证数字签名
verification_result = pow(unblinded_signature2,e1,n1)
# 计算验证结果的哈希值
verification_bytes = verification_result.to_bytes((verification_result.bit_length() + 7) // 8, byteorder="big")
verification_hash = hashlib.sha256(verification_bytes).digest()
print("verification_hash",verification_hash)
print("unblinded_signature2",unblinded_signature2)
# 将哈希值转换为整数类型
hash_int = int.from_bytes(hash_value, byteorder="big")# 检查验证结果是否与哈希值一致
if verification_result == m:print("数字签名验证通过")
else:print("数字签名验证失败")

系统测试

系统执行流程图

        本系统的执行过程如图所示。首先客户端用户查询要发送的对象,然后用户输入要盲化的金额、输入发送对象名、输入备注,然后使用密钥对金额进行盲化,并将这些信息作为盲化请求发送给服务端,服务端用户首先可以查看到用户发送过来的盲化请求,然后输入序号可以下载密钥,然后解密,再用密钥生成自己的签名值,发送给客户端用户,客户端用户接收到该签名值之后用密钥解盲。

用户查询发送对象

客户端用户先点击按钮按钮查询可发送的对象。

用户发送信息

        用户输入要交易(盲化)的金额,输入要发送的对象名,输入备注,点击发送按钮将这些值以及盲化金额发送给交易方。

服务端(交易方)可以查询被交易方发过来的盲化请求。

下载用户公钥,交易方下载密钥。

 签名者验证发送方身份

服务端生成签名值

然后点击按钮将该值发送给客户端用户。

发送方接收到服务端返回的签名进行解盲

发送方解盲后发送给第三方,第三方验证签名

第三方验证签名

数据库设计 

数据表建立语句

验证签名表
CREATE TABLE `verify_sign` (`id` int NOT NULL AUTO_INCREMENT,`userfrom` varchar(255) DEFAULT NULL,`d` text,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci用户信息表
CREATE TABLE `user_info` (`id` int NOT NULL AUTO_INCREMENT,`userfrom` varchar(255) DEFAULT NULL,`m` text,`k` text,`n` text,`e` text,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
服务端盲签名回应表
CREATE TABLE `blind_response2` (`id` int NOT NULL AUTO_INCREMENT,`userfrom` varchar(255) DEFAULT NULL,`userto` varchar(255) DEFAULT NULL,`sign_sig` text,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
客户端用户请求发送表
CREATE TABLE `blind_payrequest2` (`id` int NOT NULL AUTO_INCREMENT,`userfrom` varchar(255) DEFAULT NULL,`userto` varchar(255) DEFAULT NULL,`payment_description` varchar(255) DEFAULT NULL,`payment_time` datetime DEFAULT NULL,`payment_amount` text,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
用户密钥表
CREATE TABLE `user_keys` (`id` int NOT NULL AUTO_INCREMENT,`user` varchar(255) DEFAULT NULL,`public_key` TEXT,`private_key` TEXT,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【OpenVINO 】在 MacOS 上编译 OpenVINO C++ 项目

前言 英特尔公司发行的模型部署工具OpenVINO™模型部署套件&#xff0c;可以实现在不同系统环境下运行&#xff0c;且发布的OpenVINO™ 2023最新版目前已经支持MacOS系统并同时支持在苹果M系列芯片上部署模型。在该项目中&#xff0c;我们将向大家展示如何在MacOS系统、M2芯片的…

鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台

随着企业的快速发展&#xff0c;招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求&#xff0c;建立一个公平、公开、公正的采购环境至关重要。在这个背景下&#xff0c;我们开发了一款电子招标采购软件&#xff0c;以最大限度地控制采购成本&#…

NFS 共享存储实验

一、服务器部署 第一步、安装nfs和rpcbind包 [rootserver ~]# yum install -y nfs-utils rpcbind截图&#xff1a; 第二步、这里选择一个 lvm 挂载点做 NFS 共享目录 [rootserver ~]# df -HT截图&#xff1a; 第三步、修改配置文件 [rootserver ~]# vi /etc/exports /home …

神经网络的核心:简单易懂理解 PyTorch 非线性激活函数

目录 torch.nn子函数非线性激活详解 nn.Softmin Softmin 函数简介 函数工作原理 参数详解 使用技巧与注意事项 示例代码 nn.Softmax Softmax 函数简介 函数工作原理 参数详解 使用技巧与注意事项 示例代码 nn.Softmax2d Softmax2d 函数简介 函数工作原理 输入…

2024最新前端源码分享(附效果图及在线演示)

分享10款非常有趣的前端特效源码 其中包含css动画特效、js原生特效、svg特效以及小游戏等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 粒子文字动画特效 基于canvas实现的粒子文字动画特效 会来回切换设定的文字特效 图…

在版权付费方面,OpenAI 比人想象中的还要「小气」

随着新闻出版商与AI公司达成“使用新闻训练AI模型”的协议&#xff0c;像 OpenAI 等科技企业愿意为受版权保护的信息支付的价格逐渐浮出水面。 据 The Information 报道&#xff0c;OpenAI 每年愿意向出版商提供 100万到500万美元来支付受版权保护的新闻文章训练其AI模型。 但…

【leetcode】力扣热门之合并两个有序列表【简单难度】

题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 用例 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[] 输入&#xff1a;l1 []…

王中阳Go赠书活动第一期:《TVM编译器原理与实践》

文章目录 前言TVM编译器的实现过程关于《TVM编译器原理与实践》编辑推荐内容简介作者简介图书目录书中前言/序言《TVM编译器原理与实践》全书速览入手《TVM编译器原理与实践》传送门&#xff1a;结束语参加抽奖 前言 随着人工智能的发展&#xff0c;计算机视觉、自然语言处理和…

MySQL复习汇总(图书管理系统)

MySQL图书管理系统&#xff08;49-94&#xff09;源码_71.备份book数据库到e盘的mybook.sql文件(备份文件中要求包含建库命令)-CSDN博客 CROSS JOIN&#xff1a;交叉连接&#xff08;笛卡尔积&#xff09; -- 1、 创建一个名称为book的数据库。 -- 2、 打开book数据库…

Vue2-组件的基本应用

个人练习&#xff0c;仅供参考。 1.先在components中创建公用的内容&#xff08;public.vue&#xff09;。components文件夹下放组件供其他页面调用。 2.在用到组件的页面导入该公用组件&#xff08;import navTitle from "/components/public.vue";&#xff09;。 …

linux账户文件/etc/passwd详解

linux 账户文件/etc/passwd Linux 的/etc/passwd 文件是系统中最重要的文件之一&#xff0c;它存储了系统中所有用户的基本信息&#xff0c;包括用户名、密码、用户 ID、组 ID、主目录、登录 shell。 /etc/passwd 文件中的每行记录对应一个用户 每条记录的格式如下&#xff1a…

论文阅读记录SuMa SuMa++

首先是关于SuMa的阅读&#xff0c;SuMa是一个完整的激光SLAM框架&#xff0c;核心在于“基于面元(surfel)”的过程&#xff0c;利用3d点云转换出来的深度图和法向量图来作为输入进行SLAM的过程&#xff0c;此外还改进了后端回环检测的过程&#xff0c;利用提出的面元的概念和使…

qt-C++笔记之QProcess

qt-C笔记之QProcess code review! 文章目录 qt-C笔记之QProcess一.示例&#xff1a;QProcess来执行系统命令ls -l命令并打印出结果说明 二.示例&#xff1a;QProcess来执行系统命令ls -l命令并打印出结果&#xff0c;代码进一步丰富三.示例&#xff1a;使用 QProcess 在 Qt 中…

深入浅出理解Dilated Convolution(空洞卷积,膨胀卷积)

温故而知新&#xff0c;可以为师矣&#xff01; 一、参考资料 github仓库&#xff1a;Multi-Scale Context Aggregation by Dilated Convolutions 图片素材来源&#xff1a;Convolution arithmetic 理解Dilation convolution Dilated Convolution —— 空洞卷积&#xff08;膨…

汪林望教授将于每周三以互动问答直播形式教您如何用龙讯旷腾计算软件PWmat计算不同材料性质

打开VX→搜索“汪林望计算讲座”&#xff0c;关注汪老师的频道&#xff0c;每周三下午16:00我们准时直播&#xff01; 大家提前准备好问题&#xff0c;可直接提问讨论&#xff0c;当面请教 汪林望教授 中科院半导体所首席科学家 北京龙讯旷腾科技有限公司创始人 美国劳伦斯…

竹云董事长董宁受邀出席2023粤港澳大湾区创新战略学术研讨暨数字科技发展报告会议

科技与创新共舞&#xff0c;数字与产业交融。12月28日&#xff0c;2023 年粤港澳大湾区创新战略学术研讨暨数字科技发展报告会议在深商报告厅举行&#xff0c;深圳市科学技术协会党组成员、驻会副主席石兴中&#xff0c;深圳市商业联合会副会长、深商总会秘书长石庆&#xff0c…

React Native集成到现有原生应用

本篇文章以MacOS环境开发iOS平台为例&#xff0c;记录一下在原生APP基础上集成React Native React Native中文网 详细介绍了搭建环境和集成RN的步骤。 环境搭建 必须安装的依赖有&#xff1a;Node、Watchman、Xcode 和 CocoaPods。 安装Homebrew Homebrew是一款Mac OS平台下…

电商API接口|电商平台使用的物流API的安全风险

电子商务平台的物流 API 如果出现安全漏洞&#xff0c;则消费者的个人信息会被大量暴露。 物流 API 整合了企业和第三方供应商之间的数据和服务&#xff0c;以解决各种市场需求。如果 电商API 接口集成不当&#xff0c;可能会出现泄露个人身份信息 (PII) 的风险。许多使用 API…

京东商品详情API接口(item_get-获得JD商品详情)电商领域的重要角色

电商API接口在电商领域中扮演着重要的角色&#xff0c;它们为电商平台提供了许多功能和便利。以下是电商API接口的一些主要用途&#xff1a; 商品信息查询&#xff1a;通过API接口&#xff0c;第三方开发者或商家可以查询电商平台上的商品信息&#xff0c;包括商品详情、价格、…

Spark六:Spark 底层执行原理SparkContext、DAG、TaskScheduler

Spark底层执行原理 学习Spark运行流程 学习链接&#xff1a;https://mp.weixin.qq.com/s/caCk3mM5iXy0FaXCLkDwYQ 一、Spark运行流程 流程&#xff1a; SparkContext想西苑管理器注册并向资源管理器申请运行Executor资源管理器分配Executor&#xff0c;然后资源管理器启动Ex…