使用Crypto实现RSA算法的数字签名和检验

总的来说,需要用到的对象有三个:

Crypto.PublicKey.RSA:用来生成RSA算法的密钥对象

Crypto.Hash.SHA384:用来获取信息的摘要对象

Crypto.Signature.pkcs1_15:用来实现数字签名和检验对象

前提条件

    创建RSA对象,生成密钥 key = RSA.generate(1024),参数表示RSA模块的长度,至少为1024,必须是1024的倍数,推荐是2048,一般可以用到3072。

一、数字签名的过程

1. 创建一个数字签名对象,signer = pkcs1_15.new(key),参数是之前生成的密钥对中的私钥

2. 创建一个HASH对象,hasher = SHA384.new(message.encode()),参数是要发送和签名的文本信息的二进制形式。

3. 调用签名对象的方法完成签名,sign_obj = signer.sign(hasher),参数是哈希对象,返回的是签名内容(byte string)。

二、检验签名的过程

1. 创建一个数字签名(检验)对象,verifer = pkcs1_15.new(key.publickey()),其参数为之前的密钥对中的公钥

2. 创建一个HASH对象,hasher = SHA384.new(message.encode()),与数字签名中的对象相同。

3. 调用签名对象的检验方法,verifer.verify(hasher, sign_new),参数1表示使用的信息摘要算法对象,参数2是收到的签名内容(byte string);如果校验失败,将抛出异常,否则,正常执行。

完整代码参考:

from Crypto.PublicKey import RSA
from Crypto.Hash import SHA384
from Crypto.Signature import pkcs1_15

# 生成RSA密钥对
key = RSA.generate(1024)

# 待签名内容(发送的文本内容)
message = 'I am MKing hello everyone'

# 签名
signer = pkcs1_15.new(key)
hasher = SHA384.new(message.encode()) #Hash对象,取内容摘要
#hasher.update(message.encode()) # 换种方式使用也可以
sign_obj = signer.sign(hasher)     #用私钥对消息签名

print('签名内容:', sign_obj)

# 将签名写入文件,模拟发送(同时还发送了文本内容,为了方便,不写文件,后面直接引用)
with open('sign.bin', 'wb') as f:
    f.write(sign_obj)

# 读取签名内容,模拟接收
with open('sign.bin', 'rb') as f:
    sign_new = bytearray(f.read())  # 签名内容(二进制),并转成bytearray,以便修改

#sign_new.append(0x32)  # 模拟错误的签名
print('收到签名:', sign_obj)

# 验证签名
verifer = pkcs1_15.new(key.publickey()) # 使用公钥创建校验对象
hasher = SHA384.new(message.encode()) # 对收到的消息文本提取摘要
#hasher.update(message.encode())

try:
    verifer.verify(hasher, sign_new) # 校验摘要(本来的样子)和收到并解密的签名是否一致
    print("The signature is valid.")
except (ValueError, TypeError):
    print("The signature is not valid.")

参考资料:

[1] Crypto.Signature package.https://pycryptodome.readthedocs.io/en/latest/src/signature/signature.html

你可能感兴趣的:(编码相关,RSA,数字签名)