非对称加密会生成一个密钥对:公钥和私钥。公钥公之于众,而私钥需要保密,不公开。一般密钥的使用方法如下表,对于加密的应用场景,发送者使用公钥加密消息,接收者使用私钥解密密文,目的是在发送者和接收者之间安全地、秘密地传递消息;对于数字签名的使用场景,发送者使用私钥对消息摘要进行签名,接收者使用公钥对签名进行验签,验签的作用是鉴别发送者身份的真实性和验证消息的完整性。
Algorithm | Sender uses.. | Receiver uses… |
---|---|---|
Encryption | Public key | Private key |
Signature | Private key | Public key |
我们使用python和C语言来介绍如何生成 RSA 签名并验证签名,使用到的加密库是 Cryptodome 和 mbedtls。首先使用 python 生成签名,在 c 代码中进行验签;然后也在 c 代码中生成签名,在python里进行验签,目的是使用两种编程环境,方便相互验证。
在python中生成签名
导入 python 包,需要用到 Cryptodome 的 PublicKey、Signature、Hash 以及 base64 编码解码这几个模块。
|
|
生成公钥和私钥,并输出为 PEM 格式。
|
|
私钥:
|
|
公钥:
|
|
定义将要签名数据,并计算哈希值,哈希算法使用 SHA256。
|
|
|
|
对哈希值进行签名,并输出签名数据为16进制字符串
|
|
|
|
最终对签名数据进行 base64 编码,相比于16进制字符串数据,base64 编码得到的数据长度相对较小,这应该是对二进制数据使用 base64编码的一个优势。
|
|
|
|
在c中验证签名
在c中使用 mbedtls 库进行签名验签,使用到 pk.h、md.h 和 base64.h 这几个头文件定义的接口。
先定义和实现验证签名的接口 rsa_pkcs1v15_sha256_verify,输入参数有原始消息 msg,PEM 格式的公钥 public_key_pem,以及base64 编码后的签名数据 sign_base64。
|
|
测试验签代码如下
|
|
输出,返回值为0,验签成功。
|
|
在c中生成签名
定义生成签名的接口 rsa_pkcs1v15_sha256_sign,输入参数有原始数据msg、用于签名的私钥priavte_key_pem、保存签名输出数据的地址sign_base64。
|
|
生成签名的测试代码
|
|
输出结果
|
|
签名数据 KYiZF/C18O3wgCZvDptfM8Vh/OPMrcAf6ne9eszSuxgGMK57cKCQuWc33JF8iQmKWrSo+ezzkPJIfXGTj3z3Js9vv1DC2tX3oBh9CdZF+yc5MqZAT5LEEqmwNKWiT4iNwwnbXiJtNSy8/T2PRRN0PBy/TZn3HKc1AMKMYMLUjf8=
与在python中生成的一致,说明这段c代码也是正确的。
在python中验证签名
python 验签的测试代码比较简单,如下所示
|
|
打印输出验签结果,也是验签成功的。
|
|