前言
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA算法的原理,目前网络上有许多优秀的文章,特别推荐阅读阮一峰老师的文章:
本文主要描述如何使用RSA来对文件进行不对称加密。
安装
crypto这个模块的安装比较特殊,可能会有点小坑,安装时需要注意。
crypto,pycrypto,pycryptodome的功能是一样的。crypto与pycrypto已经没有维护了,后面可以使用pycryptodome。
但是,三个名字,再分Linux和Windows操作系统,再分Python2和Python3,叠加起来就有12种情况了,非常复杂。
在 Windows 中,不管是 Python2 和 Python3 ,都不能用 crypto 和 pycrypto ,可以用 pycryptodome 。
在 Linux 中,不管是 Python2 和 Python3 ,都不能用 crypto ,可以用 pycrypto 和 pycryptodome 。
所以,总结一句话,直接都用 pycryptodome 就行了,(保证pip正常能用的情况下)安装命令如下:
pip install pycryptodome
安装之前,最好先把 crypto 和 pycrypto 卸载了(uninstall),避免不必要的麻烦。
生成RSA公钥和私钥
from Crypto import Random
from Crypto.PublicKey import RSA
def generate_Key():
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
private_key = rsa.exportKey()
# 写入私钥文件
with open('private_rsa_key.bin', 'wb') as f:
f.write(private_key)
public_key = rsa.publickey().exportKey()
# 写入公钥文件
with open('rsa_public.pem', 'wb') as f:
f.write(public_key)
上面的代码中,生成了一对公钥和私钥。
导入了 RSA ,通过 RSA 的 generate() 方法实例化一个对象 rsa 。再通过 rsa 的 exportKey() 方法和 publickey() 方法生成公钥和私钥。
执行这个函数,可以看到,生成了一对公钥和私钥
当然每次运行的结果都不一定,公钥是公开的,任何人都可以看到,但是私钥一定要保存好,否则一旦泄露,意味着你的信息也不安全了。
进行加密和解密
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
import base64
# 加密
def encryption(keys):
with open('rsa_public.pem') as f:
key = f.read()
pub_key = RSA.importKey(str(key))
cipher = PKCS1_cipher.new(pub_key)
rsa_text = base64.b64encode(cipher.encrypt(bytes(keys.encode("utf8"))))
return rsa_text.decode('utf-8')
# 解密
def decrypt(keys):
with open('private_rsa_key.bin') as f:
key = f.read()
pri_key = RSA.importKey(key)
cipher = PKCS1_cipher.new(pri_key)
back_text = cipher.decrypt(base64.b64decode(keys),0)
return back_text.decode('utf-8')
上面的函数,我们将保存的公钥和私钥读出来,然后进行加密和解密的过程,不过千万要注意的是,私钥不要泄露。
签名和验签
RSA还可以用来签名和验签,正好与加密相反的是,他是使用私钥来签名,公钥来验签
废话不多说,上代码
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
import base64
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
message = "需要加密的信息"
# 使用私钥生成签名
with open('private_rsa_key.bin') as f:
key = f.read()
pri_key = RSA.importKey(key)
signer = PKCS1_signature.new(pri_key)
digest = SHA.new()
digest.update(message.encode("utf8"))
sign = signer.sign(digest)
signature = base64.b64encode(sign)
print(signature.decode('utf-8'))
# 使用公钥验证签名
with open('rsa_public.pem') as f:
key = f.read()
pub_key = RSA.importKey(key)
verifier = PKCS1_signature.new(pub_key)
digest = SHA.new()
digest.update(message.encode("utf8"))
print(verifier.verify(digest, base64.b64decode(signature)))
继续使用之前写入文件中的私钥和公钥,使用私钥来生成信息的签名,然后使用公钥来验证签名。
生成签名时,使用 RSA 的 importKey() 方法对(从文件中读取的)私钥字符串进行处理,处理成可用的私钥用于生成签名。
从 Crypto.Signature 中导入 PKCS1_v1_5 ,重命名为 PKCS1_signature 。然后实例化一个签名对象 signer ,传入的参数是私钥,通过的 signer 的 sign() 方法对信息生成签名。
信息需要先转换成 sha 字符串,使用 Crypto.Hash 中的 SHA 来转换。生成的签名是字节串,为了显示得更友好,可以将结果转换成 base64 字符串。
验证签名时,使用 RSA 的 importKey() 方法对(从文件中读取的)公钥字符串进行处理,处理成可用的公钥用于验证签名。
实例化一个验证对象 verifier ,传入的参数是公钥,通过的 verifier 的 verify() 方法对签名进行验证。验证结果是一个布尔值,验证成功返回 True , 不成功返回 False 。
- Post link: https://www.godhearing.cn/python-shi-yong-rsa-fei-dui-cheng-jia-mi/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.