使用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

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
椭圆曲线加密算法(Elliptic Curve Cryptography,简称ECC)是一种基于椭圆曲线数学问题的公钥加密算法。在C++中,你可以使用一些库来实现椭圆曲线加密算法,如Crypto++、OpenSSL等。下面是一个使用Crypto++库实现椭圆曲线加密的简单示例: ```cpp #include <iostream> #include <cryptopp/eccrypto.h> #include <cryptopp/osrng.h> using namespace CryptoPP; int main() { AutoSeededRandomPool rng; // 生成椭圆曲线参数 ECDSA<ECP, SHA256>::PrivateKey privateKey; privateKey.Initialize(rng, ASN1::secp256r1()); // 从私钥中提取公钥 ECDSA<ECP, SHA256>::PublicKey publicKey; privateKey.MakePublicKey(publicKey); // 显示私钥和公钥 std::cout << "Private key: " << privateKey.GetPrivateExponent() << std::endl; std::cout << "Public key: " << publicKey.GetPublicElement().x << " " << publicKey.GetPublicElement().y << std::endl; return 0; } ``` 上述示例中,我们使用Crypto++库生成了一个ECDSA(椭圆曲线数字签名算法)的私钥和公钥。其中,`AutoSeededRandomPool`用于生成随机数,`ECDSA<ECP, SHA256>`指定了使用椭圆曲线类型和哈希算法(这里使用了secp256r1曲线和SHA256哈希算法)。私钥和公钥可以通过`GetPrivateExponent()`和`GetPublicElement()`方法获取。 请注意,这只是一个简单的示例,并没有完整的加密/解密过程。如果你想要实现完整的椭圆曲线加密算法,建议使用成熟的密码学库进行开发,以确保安全性和正确性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值