RSA算法实战

温故知新
在 HTTPS系列之密码学基础--证书及签名 文章中对证书和签名进行了简单的介绍。核心在讲述下面的内容:
公钥加密,私钥解密。私钥签名,公钥验证。
本文将通过RSA算法来对实践一下。
RAS算法
概念
RSA算法是一种非对称加密算法,在公开密钥加密和电子商务中被广泛使用。RSA是由Ron Rivest、Adi Shamir、Leonard Adleman在1997你年一起提出来的。RSA是他们三人姓氏开头字母拼在一起组成的。
安全性
大质数做因式分解困难。理论证明有兴趣可以查看维基百科。
公私钥生成流程
1.
随机找两个质数 P 和 Q ,P 与 Q 越大,越安全。(例如:61和53)
2.
计算p和q的乘积n。(n = 61×53 = 3233,n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。)
3.计算 n 的欧拉函数 φ(n)。(根据公式φ(n) = (p-1)(q-1)算出φ(3233)等于60×52,即3120)
4.随机选择一个整数 e,条件是1< e < φ(n),且 e 与 φ(n) 互质。(条件是1< e < φ(n),且e与φ(n) 互质。1到3120之间,随机选择了17。)
5.有一个整数 d,可以使得 ed 除以 φ(n) 的余数为 1。(ed ≡ 1 (mod φ(n)),即17*2753 mode 3120 = 1)
6.将n和e封装成公钥,n和d封装成私钥。(n=3233,e=17,d=2753,所以公钥就是 (3233,17),私钥就是(3233, 2753)。)
RSA加密
首先对明文进行比特串分组,使得每个分组对应的十进制数小于n(密钥长度),然后依次对每个分组m做一次加密,所有分组的密文构成的序列就是原始消息的加密结果,即m满足0≤m<n。
加密算法为: c≡ me mod n; c为密文,且0≤c<n。
RSA解密
对于密文0≤c<n,解密算法为: m≡ cd mod n。
RSA签名验证
RSA密码体制既可以用于加密又可以用于数字签名。
已知公钥(e,n),私钥d。
1.对于消息m签名为:sign ≡ md mod n
2.验证:对于消息签名对(m,sign),如果m ≡ signe mod n,则sign是m的有效签名
图解RSA算法
msg = “待加密字符串”;
msgHash = “待签名字符串,由msg进行hash得到”;
encryptedMsg = “msg加密后的字符串”;
signedMsg = “msgHash签名后的字符串”;
注意:
B在签名操作的时候,需要将原文msg和签名后的signedMsg一起发送给A。
A在验签操作的时候,需要将原文msg进行hash得到msgHash,再对signedMsg进行验签。

这个流程不正是 HTTPS系列之密码学基础--证书及签名 中冰女给卡尔写信,卡尔回信的一个流程吗!!
python实现
代码
import rsa
# rsa加密
def rsaEncrypt(str):
# 生成公钥、私钥
(pubkey, privkey) = rsa.newkeys(512)
print("公钥:\n%s\n私钥:\n:%s" % (pubkey, privkey))
# 明文编码格式
content = str.encode("utf-8")
# 公钥加密
crypto = rsa.encrypt(content, pubkey)
return (crypto, privkey)
# rsa签名
def rsaSignature(str):
# 生成公钥、私钥
(pubkey, privkey) = rsa.newkeys(512)
print("公钥:\n%s\n私钥:\n:%s" % (pubkey, privkey))
# 明文编码格式
content = str.encode("utf-8")
# 私钥签名
sign_content = rsa.sign(content, privkey, hash_method= "MD5")
return (sign_content, privkey, pubkey)
# rsa签名验证
def verifySignature(str, sign_content, publicKey):
verifyState = rsa.verify(str.encode("utf-8"), sign_content, publicKey)
return verifyState
# rsa解密
def rsaDecrypt(str, pk):
# 私钥解密
content = rsa.decrypt(str, pk)
con = content.decode("utf-8")
return con
if __name__ == "__main__":
str, pk = rsaEncrypt("hello")
print("加密后密文:\n%s" % str)
content = rsaDecrypt(str, pk)
print("解密后明文:\n%s" % content)
sign_str, pk, pubkey= rsaSignature("无情剑客")
print("签名后的内容是:\n%s" %sign_str)
verifySignature("无情剑客", sign_str, pubkey)
注意一下这里的钥匙,包括了d, e, n, p, q的值。

运行结果
公钥:
PublicKey(6724473421617242406033381907376973847701520125454157522060405520033944305101855214760573237185166023091650432736600268403970570744813381953262177544625259, 65537)
私钥:
:PrivateKey(6724473421617242406033381907376973847701520125454157522060405520033944305101855214760573237185166023091650432736600268403970570744813381953262177544625259, 65537, 2451148901674081874936775567775890386312184174999990372530036887072812234444050202758587277441923426272269899052384408399111077953647079855236631759734273, 4010988364819606716981934755585055372145464201482196612705679395958113663731500801, 1676512821776702924436322032243523484844142298453208720288227205443678059)
加密后密文:
b"Q\xd3*\xe3\x85\x01\x19\x12\x85\xc9\xf0PRbh\x7f\x01\xe6\x86\xd2:J\x12\xee\x9e\x11\x9fU;\xc5$H\xado\xab\x19\xeb\xf2'k\xab\xda\xc6 \x1c\xc6\xb0\xb2\x0eC\xccZ9\x89\xa9\x91\xaee\x81,|Qp\xe0"
解密后明文:
hello
公钥:
PublicKey(8193891274525958296363775492883760563553517922477344673165506854369989686854027952057004806850378754875438172242728613760836138261927106484501676466689559, 65537)
私钥:
:PrivateKey(8193891274525958296363775492883760563553517922477344673165506854369989686854027952057004806850378754875438172242728613760836138261927106484501676466689559, 65537, 2480284649954162697152212921370035889036341128615981256790169293330360792526935074929436520962790960483160278292175246636411096362939467659267719544939569, 7459041359283394484872085428762006331855202857395448848532451826326422789817766373, 1098518010538711151640961069219349068251138170748833890300964836048222283)
签名后的内容是:
b'\x1f\xdc\xa7\x01\xca\xed^\xd5\x10_\x19\x11N\xbd\xaa\x9a\x99\x02\xe3\x95\x15\xc9\x8f\\\xe4W\xc2\xc3\xab"s2K\xa7+\x96[\xdf\x9b\xcc^~\x03\xce\xdbvQ\xd6.\xa1\x0bn\xee\xc2\xf0c\x0e~^a\xe4\xddXN'
hash算法是:MD5
参考
RSA非对称加密图解和原理[1] http://tool.chacuo.net/cryptrsapubkey 通俗易懂RSA[2] 维基百科 HTTPS系列之密码学基础--证书及签名 https://www.ruiwen.com/wenxue/qingshi/74858.html python3 RSA加解密[3]
公众号
更多内容, 欢迎关注我的微信公众号: 无情剑客。

References
[1]
RSA非对称加密图解和原理: https://www.jianshu.com/p/2f7e8f2efcf3[2]
通俗易懂RSA: https://www.cnblogs.com/jockming/p/12111579.html[3]
python3 RSA加解密: https://blog.csdn.net/whatday/article/details/97617461/