python rsa模块学习笔记
一. 简介与历史
Python-RSA的历史始于2006年。作为阿姆斯特丹大学的学生作业。它起初只是一个用于计算大素数以及使用这些大数进行RSA加密,解密,签名和验证的模块,它还包括生成公钥和私钥。
二. 安装
- 最简单的方式:pip install rsa
- 也可以通过pycharm安装 操作流程:file–> settings–>Project: untitled–>Project Interpreter–>点击右上角的 + -->搜索rsa并选择–> 点击左下角 INSTALL PACKAGE 等待安装完成即可。
- 通过git获取源码 git clone https://github.com/sybrenstuvel/python-rsa.git
三. 作用
- 在使用rsa前,我们必须的到一对密钥,及公钥和私钥(public key、 private key)
- public key用于加密消息,以便只能由private key的所有者读取。因此,它也称为encryption key(加密密钥)。解密消息只能使用私钥完成,因此也称为decryption key(解密密钥)。
- 发送者用private key 签名信息并生成sign,接收者接收到信息后,可以用sign和public key 来验证信息是否由发送者签名,以及信息是否被修改过。
四. 使用
- 使用rsa.newkeys()生成密钥对,
- 并用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服务器偏向于使用这种编码格式. - 将密匙以文件的形式保存到本地,通过字符写入操作
- 将公钥和私钥从文件中读取出来使用文件内容读取操作和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()解密
假设小明想发送一条消息,只有小美可以阅读。
- 小明生成一个密钥对,并将公钥提供给小美。这样做是为了使小美知道密钥确实是小明提供的密钥
- 小美编写一条消息,并以UTF-8对其进行编码。RSA模块仅对字节进行操作,而不对字符串进行操作,因此此步骤是必需的。
- 小美使用小明的公钥加密消息,然后发送加密的消息。
- 小明收到消息,并用他的私钥解密。
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
写作不易,且看且珍惜
转载前注明出处(虽然不会有人转载,大佬的样子还是要装下的!!!),谢谢