python rsa模块学习笔记

python rsa模块学习笔记

一. 简介与历史

Python-RSA的历史始于2006年。作为阿姆斯特丹大学的学生作业。它起初只是一个用于计算大素数以及使用这些大数进行RSA加密,解密,签名和验证的模块,它还包括生成公钥和私钥。

二. 安装

  1. 最简单的方式:pip install rsa
  2. 也可以通过pycharm安装 操作流程:file–> settings–>Project: untitled–>Project Interpreter–>点击右上角的 + -->搜索rsa并选择–> 点击左下角 INSTALL PACKAGE 等待安装完成即可。
  3. 通过git获取源码 git clone https://github.com/sybrenstuvel/python-rsa.git

三. 作用

  1. 在使用rsa前,我们必须的到一对密钥,及公钥和私钥(public key、 private key)
  2. public key用于加密消息,以便只能由private key的所有者读取。因此,它也称为encryption key(加密密钥)。解密消息只能使用私钥完成,因此也称为decryption key(解密密钥)。
  3. 发送者用private key 签名信息并生成sign,接收者接收到信息后,可以用sign和public key 来验证信息是否由发送者签名,以及信息是否被修改过。

四. 使用

  1. 使用rsa.newkeys()生成密钥对,
  2. 并用save_pkcs1方法,转换编码格式
    save_pkcs1(format:str=‘PEM’) 默认编码格式为PEM
    PEM - Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN RSA XXX KEY-----"开头, "-----END RSA XXX KEY-----"结尾,内容是BASE64编码.Apache和*NIX服务器偏向于使用这种编码格式.
    DER - Distinguished Encoding Rules,打开看是二进制格式,不可读,Java和Windows服务器偏向于使用这种编码格式.
  3. 将密匙以文件的形式保存到本地,通过字符写入操作
  4. 将公钥和私钥从文件中读取出来使用文件内容读取操作和PublicKey.load_pkcs1()以及PrivateKey.load_pkcs1()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import rsa
(pubkey, privkey) = rsa.newkeys(512)  # 创建公钥和私钥,512为设定你加密字符串的最大可支持加密长度为512位=64字节,你也可以按需设置任意长度,越长加密越慢,越短越快
# 将公钥和私钥以pem编码格式保存
pub = pubkey.save_pkcs1()
pri = privkey.save_pkcs1()
print(f"公钥初始的值为:{pubkey},以pem格式的保存后的数据为:{pub}")
print(f"私钥初始的值为:{privkey} \n 以pem格式的保存后的私钥数据为:{pri}")
#  打印结果
# 公钥初始的值为:PublicKey(7481244465315159030174941866408088977078689270761513884333182534899112302828868853012354970827459273420757239091319237996571359037764144367408861808720513, 65537)
# 以pem格式的保存后的公钥数据为:b'-----BEGIN RSA PUBLIC KEY-----\nMEgCQQCO14+r/YbVU9gmeglgJoi8PNUvVaLzRFOBi/dNN5muCB6kRCzBylNhWpMi\nGAKy+wNjY/V1JKp7eILkc3KyMHqBAgMBAAE=\n-----END RSA PUBLIC KEY-----\n'
# 私钥初始的值为:PrivateKey(7481244465315159030174941866408088977078689270761513884333182534899112302828868853012354970827459273420757239091319237996571359037764144367408861808720513, 65537, 3506665680913321791475716605798100085247726562224742435766529354251275320158796528099874018589937145723483840242318255274732417780923351826009689191428353, 5643184159408851232131776560683191883064718200648061020021754396931515736448351153, 1325713330273249992945906759133446589093679828123455507108369540590727121)
# 以pem格式的保存后的私钥数据为:b'-----BEGIN RSA PRIVATE KEY-----\nMIIBPAIBAAJBAI7Xj6v9htVT2CZ6CWAmiLw81S9VovNEU4GL9003ma4IHqRELMHK\nU2FakyIYArL7A2Nj9XUkqnt4guRzcrIweoECAwEAAQJAQvQ5jNWeYNoXJBnp0R7e\n0tT03GYYpkxtk/iGZ7RaxGNXkIecc0u+bg4kSXC8BpcxpVS7xqWIPO4+ognbOkUx\nAQIjAL5ffVWlM15Ijcy5isAEzO6UnspteTYaA1H098CNMrSgu7ECHwDAFXC9M3X5\nKGM7tRw7/Vb7hroNJ23crvKG7Y/N79ECImrGeC/PRq59FztaXd4xUxgFt8JmAHQ9\nxtrzAPq4t1XkSSECHwCEbkPMLi6oGbBQ+gz9Ty0pPToI16ZnADc1z5PV6AECIhGm\n7Hx73R+hCWXIih/bttl0W7hl6mlIOqZXo30IfFUPHtQ=\n-----END RSA PRIVATE KEY-----\n'
# 将公钥保存到文件 ,将字节写入文件需要加上decode('utf-8'),python3新增
with open("public.pub", 'w+') as file:  # public.pub,保存的文件名,可更改路径,这里保存在当前路径下
    file.write(pub.decode("utf-8"))
# 将私钥保存到文件
with open("private.pem", 'w+') as file:
    file.write(pri.decode('utf-8'))
   
# 取出公钥
with open("public.pub", "r") as file_pub:
    # 从文件中读出数据
    pub_data = file_pub.read()
    # 将读出数据通过PublicKey.load_pkcs1()转换为公钥
    pubkey = rsa.PublicKey.load_pkcs1(pub_data)
# 取出私钥
with open("private.pub", "r") as file_pri:
    pri_data = file_pri.read()
    # 将读出数据通过PrivateKey.load_pkcs1()转换为私钥
    prikey = rsa.PrivateKey.load_pkcs1(pri_data)

五. 通过rsa加密解密

要加密或解密消息,需要使用rsa.encrypt()加密, rsa.decrypt()解密
假设小明想发送一条消息,只有小美可以阅读。

  1. 小明生成一个密钥对,并将公钥提供给小美。这样做是为了使小美知道密钥确实是小明提供的密钥
  2. 小美编写一条消息,并以UTF-8对其进行编码。RSA模块仅对字节进行操作,而不对字符串进行操作,因此此步骤是必需的。
  3. 小美使用小明的公钥加密消息,然后发送加密的消息。
  4. 小明收到消息,并用他的私钥解密。
1
2
3
4
5
6
7
8
9
10
11
12
import rsa
# 小明生成密钥对
(ming_pubkey, ming_privkey) = rsa.newkeys(512)
# 小美编写一条消息,并以UTF-8对其进行编码
message = 'hello dear xiaoMing!'.encode('utf-8')
# 小美使用小明的公钥加密消息,然后发送加密的消息
crypto = rsa.encrypt(message,  ming_pubkey)
# 小明收到消息,并用他的私钥解密
message = rsa.decrypt(crypto, ming_privkey)
print(message.decode('utf8'))

# 打印结果:hello dear xiaoMing!

六. 通过rsa签名和验证

由于小明保管私密,小美知道他是唯一一个可以可以阅读该消息的人,小明也不能确切知道它是小美发送消息,因为她没有签名。所以我们需要运用到签名和验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import rsa
# 使用rsa.sign()方法为邮件创建单独的签名
# 生成密钥对
(pubkey, privkey) = rsa.newkeys(512)
# 待加密字符串
message = 'Go left at the blue tree'
# 将消息使用私钥签名,这里使用SHA-512对消息进行哈希处理。其他哈希方法也是可能的.
signature = rsa.sign(message, privkey, 'SHA-512')

# 可以在单独的操作中计算哈希和签名(即,用于在客户端计算机上生成哈希,然后在远程服务器上使用私钥签名)。要对消息进行哈希处理,请使用rsa.compute_hash() 函数,然后使用rsa.sign_hash()函数对哈希签名:
# 待加密字符串
message = 'Go left at the blue tree'
# 用rsa.compute_hash()生成哈希数据
hash = rsa.compute_hash(message, 'SHA-1')
# 使用私钥对哈希数据签名
signature = rsa.sign_hash(hash, privkey, 'SHA-1')

# 验证签名,请使用rsa.verify() 方法。如果验证成功,此函数将返回True
result = rsa.verify(message, signature, pubkey)
print(result)
# 如果修改验证的message会报错,有兴趣的同学可以尝试下,我这里就不写了

文末

这些是我学习过程遇到了这个模块,自己进行的一些学习,记录了下来,以供有缘人参考,只写了些基本操作,想了解更多的请参考官方文档。
本文主要内容均来自于官方文档:https://stuvel.eu/python-rsa-doc/index.html
写作不易,且看且珍惜
转载前注明出处(虽然不会有人转载,大佬的样子还是要装下的!!!),谢谢