【通过OpenPGP签名,聊RSA 是与非, 公钥加密-私钥解密
OpenPGP签名
前文我们讲了 OpenPGP 数据加解密的过程 【整挺好协议 - OpenPGP 加密协议】, 本篇继续说下OpenPGP 中关于签名的部分。
签名作用
签名的主要作用是 比对传输的消息是否被篡改 ,此外还有验证身份等作用,如下
- 完整性:文件/邮件传输过程中未被更改。
- 验证发送者身份:确认发送者确实是他声称的身份。
- 不可否认:发送者不可否认已发送的文件/邮件。
签名与验签
分为签名和验签两部分,涉及到发送者和接收者之间的交互,这里主要讲其中的签名部分,传输数据加密 部分一笔带过,不再展开介绍,如需可以参考: 【整挺好协议 - OpenPGP 加密协议】
产生签名
- 传输数据
Data
通过Hash function 获取Data的哈希(记为Data-Hash
),其中Hash function为 不可逆的加密散列函数 - 对
Data-Hash
使用发送者的私钥
进行加密,得到签名(记为Signature
) - 对传输数据
Data
进行加密。
发送 签名 和 加密后的数据。
进行验签
接收者收到 签名 和 加密后的数据,
- 对签名
Signature
使用发送者的公钥
进行解密,得到Data-Hash
- 对加密后的数据 使用
接收者的私钥
进行解密,得到传输数据Data
- 对传输数据
Data
通过相同的 Hash function 获得Data的哈希(记为Data-Hash2
),比对Data-Hash2
和Data-Hash
是否一致,一致则验签成功。
流程图如下,左为签名过程,由为验签过程
签名与验签 流程细心的小伙伴到这里就会发现了 ,
发送者 对 Data-Hash
使用 发送者的私钥
进行加密,得到签名 Signature
接收者 对签名 Signature
使用 发送者的公钥
进行解密,得到 Data-Hash
私钥加密,公钥解密?这和常常说的 公钥加密,私钥解密,不一致,到底哪个是对的?
公钥加密-私钥解密 还是 私钥加密-公钥解密,哪个对?
其实两个都是对的, 只不过对应的场景不同,
公钥加密-私钥解密,指的是对于 传输的原始数据
,使用 接收端的公钥
进行加密, 使用 接收端的私钥
进行解密
私钥加密-公钥解密,指的是对于 签名的数据哈希
, 使用 发送端的私钥
进行加密, 使用 发送端的公钥
进行解密
细心的小伙伴又会发现,这个地方是不是还挺神奇的 ,对于同一份数据 (我们统称为d),使用一组钥匙对(key pair 包含一组对应的公钥 ,私钥),无论使用公钥或私钥加密,都可以用相对的私钥或公钥解密, 达到如下效果
d → 公钥加密 ,私钥解密→ d
d → 私钥加密,公钥解密 → d
公钥和私钥两者碰到一起感觉像是消失了一样,对原始数据没有影响。像不像消消乐,两块儿碰到一起 就没有了 哈哈哈
这具体是为什么呢,这就不得不提到这里用到的加密算法 - RSA非对称加密的理论基础了。
理论基础
因为就RSA 非对称加密算法而言,私钥-公钥是完全对等的,一个用作加密,另一个就可以解密,这是因为
RSA算法的数学基础建立在数论中的模幂运算和大素数分解问题上。
在RSA算法中,公钥由(n, e)组成,私钥由(n, d)组成,其中n是两个大素数p和q的乘积,e和d满足一定条件。
当原始数据M经过私钥加密后,得到密文C,计算公式为:C = M^d mod n。
接着再用公钥对密文C进行解密,计算公式为:C^e mod n。
根据模幂运算的性质,(Md)e mod n = M^(de) mod n = M。
因为e和d满足一定的数学关系,所以最终可以还原出原始数据M。
接下来,演示!
最后 ,来用开源OpenPGP 实现的库,来演示下 发送端加密数据,并签名,接收端解密数据,并验签。
示例源码:https://github.com/Wunan777/openpgp-demo
结语
至此我们再看问题 :公钥加密-私钥解密, 真的对吗 ?答案是对的。同样 ` 私钥加密-公钥解密 也是对的。
公钥加密-私钥解密,是对要 传输的原始数据
的加解密,用于数据加密场景
私钥加密-公钥解密,是对要 签名的数据哈希
的加解密,用于签名验签场景
基于RSA非对称加密的理论基础 ,进行的安全场景实践,真是奇妙的设计!
Refs:
https://www.rmnof.com/article/openpgp-gnupg-introduction/
https://www.zhihu.com/question/25912483