使用Crypto实现ECC(椭圆曲线加密)算法的数字签名和检验

与RSA数字签名操作步骤相同,不同之处在于,生成密钥算法的对象和加密操作的对象不同,需要用到三类对象:

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

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

Crypto.Signature.DSS:用来实现数字签名和签名检验的对象,注意,这里与RSA算法用到的对象不同

前提条件

    创建DSS对象,生成密钥对(Key Pair) key = ECC.generate(curve='P-256'),参数表示ECC模块的长度,有效参数只有P-256, P384, 和P-521,此处采用NIST P-256(256bits长度),可以达到RSA 3072 bits的加密强度。

一、数字签名的过程

1. 创建一个数字签名对象,signer = DSS.new(key, 'fips-186-3'),第一个参数是之前生成的密钥对中的私钥,第二个参数代表生成模式,fips-186-3表示签名生成是随机的,生成规则遵循FIPS 186-3。如果要遵循RFC6979,可以使用’deterministic-rfc6979’。

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

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

二、检验签名的过程

1. 创建一个数字签名(检验)对象,verifer = DSS.new(key.public_key(), 'fips-186-3'),第一个参数为之前的密钥对中的公钥,第二个参数解释同签名过程。

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

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

完整代码参考:

from Crypto.PublicKey import ECC
from Crypto.Hash import SHA256
from Crypto.Signature import DSS

# 生成ECC密钥对
key = ECC.generate(curve='P-256')

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

# 签名
signer = DSS.new(key, 'fips-186-3')
hasher = SHA256.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_new)

# 验证签名
verifer = DSS.new(key.public_key(), 'fips-186-3') # 使用公钥创建校验对象
hasher = SHA256.new(message.encode()) # 对收到的消息文本提取摘要

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

注意,第27行代码模拟收到的签名被篡改,所以,这段程序运行结果将是签名校验无效。注释掉此行,签名校验应该就通过了。

参考资料:
[1] ECC,https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html
[2] Digital Signature Algorithm (DSA and ECDSA),https://pycryptodome.readthedocs.io/en/latest/src/signature/dsa.html

你可能感兴趣的:(编码相关,ECC,椭圆曲线加密,数字签名)