欢迎光临散文网 会员登陆 & 注册

RSA算法实战

2021-11-06 17:01 作者:无情剑客Burning  | 我要投稿


温故知新

在 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/


RSA算法实战的评论 (共 条)

分享到微博请遵守国家法律