【RSA数字签名】Python3 Module Crypto 实现RSA数字签名的生成与验证

签名说明:

  • 使用HASH256对数据加密;
  • 对哈希结果进行BER编码,并使用PKCS #1.5进行填充;
  • 使用私钥对填充后的内容进行加密得到签名结果;

环境准备:

Python3 Crypto

项目目录:

请添加图片描述

1. 生成RSA公私钥,并把它们和需要加密的信息文件分别存入该路径下:

create_file.py

from Crypto.PublicKey import RSA
import re

# bit一般为1024的倍数(2048,...), RSA算法的密钥长度至少1024位才能保证其安全性
bits = 3072
i = 0
str1 = ''

key = RSA.generate(bits)

# 创建一个私钥文件,一个公钥文件,一个数据文件
private_key = key.export_key()
public_key = key.publickey().export_key()
data = "月海花千野reimportcontinuebin."

with open("private_key.pem", "wb") as prifile, \
        open("public_key.pem", "wb") as pubfile, \
        open("data.txt", "w") as datafile:
    prifile.write(private_key)
    prifile.close()  # 关闭I/O流
    pubfile.write(public_key)
    pubfile.close()  # 关闭I/O流
    datafile.write(data)
    datafile.close()  # 关闭I/O流

print("-------RSA数字签名-------")

with open('public_key.pem', "r") as pubfile:  #
    pubfile.readline()  # 读取公钥密码头"-----BEGIN PUBLIC KEY-----",但不接收
    pub_key = pubfile.read()  # 接收从第二行开始的数据,即公钥
    pubfile.close()

while True:
    if pub_key[i] == '-':  # 遇到'-'结束读取,不接收末尾'-'开始的密码尾部
        print("生成的公钥:")
        break
    str1 += pub_key[i]
    i += 1

pub_key = re.sub('\n', '', str1)  # 去掉字符串的换行符
print(pub_key)

i = 0
str1 = ''

with open('private_key.pem', "r") as prifile:
    prifile.readline()  # 读取私钥密码头-----BEGIN RSA PRIVATE KEY-----,但不接收
    pri_key = prifile.read()  # 接收从第二行开始的数据,即私钥
    prifile.close()  # 关闭I/O流

while True:
    if pri_key[i] == '-':  # 遇到'-'结束读取,不接收末尾'-'开始的密码尾部
        print("生成的私钥:")
        break
    str1 += pri_key[i]  # 将读取的私钥存入数组
    i += 1

pri_key = re.sub('\n', '', str1)  # 去掉字符串的换行符
print(pri_key)

print("私钥已存入:private_key.pem\n" + "公钥已存入:public_key.pem\n" + "数据已存入:data.txt\n")



生成与创建结果:
请添加图片描述

  • 文件例:

公钥文件:public_key.pem

请添加图片描述

私钥文件:private_key.pem

在这里插入图片描述

2.通过数字签名脚本,对数据文件进行签名并生成数字签名文件:

signature.py

注意:这里我用的是SHA256进行数据的散列加密,使用md5可在对应代码处取消注释,再注释掉HASH256加密处的代码,并导入MD5库
代码里面有详细注释(^ _ ^)

from Crypto.Signature import pkcs1_15
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
import base64

# 签名
with open("data.txt", "r") as datafile:
    data = datafile.read()


# 定义签名函数,能够使用指定的私钥对数据文件进行签名,并将签名结果输出到文件返回
def signaturen(private_key, data):
    # md5生成摘要    使用需导入MD5  # from Crypto.Hash import MD5
    # data_s_hashencode = MD5.new(data.encode('utf-8'))
    # hash256生成摘要
    data_s_hashencode = SHA256.new(data.encode('utf-8'))
    # 使用私钥对HASH值进行签名
    pri_cipher = pkcs1_15.new(private_key)
    # 使用base64对签名信息加密
    signature = base64.b64encode(pri_cipher.sign(data_s_hashencode))
    print("数字签名:")
    print(signature.decode('utf-8'))

    # 将签名结果写入文件
    sig_result = open("sig_result.txt", "wb")
    sig_result.write(signature)
    sig_result.close()   # 关闭I/O流
    return sig_result


with open('private_key.pem', 'rb') as prifile, \
        open('data.txt', 'r') as datafile:
    private_key = RSA.import_key(prifile.read())
    data = datafile.read()
    datafile.close()   # 关闭I/O流
    signaturen(private_key, data)
print("签名已写入:sig_result.txt")

签名结果:
请添加图片描述

3. 数字签名验证脚本,对私钥生成的签名文件进行验证:

verify.py

注意:如果前面的签名算法使用md5对data进行加密,则此处也需要取消对应md5加密代码处的注释,再注释掉HASH256加密处的代码,并导入MD5库
代码里面有详细注释(^ _ ^)

from Crypto.Signature import pkcs1_15
from Crypto.PublicKey import RSA
import base64
from Crypto.Hash import SHA256
import re

i = 0
str1 = ''


# 定义签名验证函数,能够使用指定的公钥对私钥生成的签名文件进行验证,返回验证结果
def Authentication(public_key, data, signature):
    # 对验证信息signature先base64解密
    signature = base64.b64decode(signature)
    # 对接收信息data进行md5进行加密生成散列值      使用需导入MD5   #from Crypto.Hash import MD5
    # data_a_hashencode = MD5.new(data.encode('utf-8'))

    # 对接收信息data进行hash256加密生成散列值
    data_a_hashencode = SHA256.new(data.encode('utf-8'))
    print("The result of signature verification:")
    print("----------------------------------")
    try:
        # 使用公钥解密并验证
        pkcs1_15.new(public_key).verify(data_a_hashencode, signature)
        print(">  Success:签名验证成功!!!")
    except:
        print(">  Error:签名无效!!!\n")
    print("----------------------------------\n")


with open('public_key.pem', "r") as pubfile:  #
    pubfile.readline()  # 读取公钥密码头"-----BEGIN PUBLIC KEY-----",但不接收
    pub_key = pubfile.read()  # 接收从第二行开始的数据,即公钥
    pubfile.close()

    while True:
        if pub_key[i] == '-':  # 遇到'-'结束读取,不接收末尾'-'开始的密码尾部
            print("-----公钥-----")
            break
        str1 += pub_key[i]
        i += 1

    pub_key = re.sub('\n', '', str1)  # 去掉字符串的换行符
    print(pub_key+'\n')

# 打开公钥文件,接收的信息文件,签名文件,对它们进行验证
with open('public_key.pem', 'rb') as pubfile, \
        open('data.txt', 'r') as datafile, \
        open('sig_result.txt', 'rb') as sigfile:
    public_key = RSA.import_key(pubfile.read())
    pubfile.close()  # 关闭I/O流
    data = datafile.read()
    print("> data文件中的数据:")
    print(data+'\n')
    datafile.close()  # 关闭I/O流
    signature = sigfile.read()
    print("> 签名信息:")
    print(signature.decode('utf8')+'\n')
    sigfile.close()  # 关闭I/O流

    Authentication(public_key, data, signature)


验证结果:
请添加图片描述

运行后的项目目录:
请添加图片描述

最后,对Python文件读写(with as)不熟的同学可以参考下图:

with open('xxx.txt', 'r') as file:
    print(file.read())

在这里插入图片描述

参考:
python实现RSA数字签名的产生和验证(二)

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值