常见的RSA加解密使用方式是:公钥加密,私钥解密。私钥签名,公钥验签。
但我在项目上却遇到了一个用python解决公钥解密的问题。查了好多资料最后完成了这需求,记录一下。
import base64
from rsa import core, PublicKey, transform
def public_key_decrypt(rsa_public_key_der_b64, qr_code_cipher_b64):
qr_code_cipher = base64.b64decode(qr_code_cipher_b64)
public_key = base64.b64decode(rsa_public_key_der_b64)
try:
rsa_public_key = PublicKey.load_pkcs1_openssl_der(public_key)
cipher_text_bytes = transform.bytes2int(qr_code_cipher)
decrypted_text = core.decrypt_int(cipher_text_bytes, rsa_public_key.e, rsa_public_key.n)
final_text = transform.int2bytes(decrypted_text)
final_qr_code = final_text[final_text.index(0) + 1:]
return final_qr_code.decode()
except Exception as ex:
_logger.exception(ex)
return None
(1)安装rsa包
pip install rsa
(2)为什么不用crpyto包?
我查了好多资料,也看了crypto代码,实在是不知道怎么用cytpto包进行公钥解密,只能进行公钥加密操作。所以最后改为使用rsa包。
rsa包实现了RSA算法的核心,如果对RSA算法有一些了解的,使用起来和用openssl感觉差不多。
rsa的PublicKey类中提供了两个无需实例化的方法来加载公钥,load_pkcs1_openssl_pem()和load_pkcs1_openssl_der()
具体使用哪个方法主要是看你“手中的RSA公钥”是哪种格式的:
load_pkcs1_openssl_pem是用来加载:符合PKCS#1.5 PEM-encoded 格式的公钥文件,具体可以搜一下PEM格式。
load_pkcs1_openssl_der是用来加载:公钥原始二进制字节流
由于RSA是基于“大整数运算”的,因此,需要将待处理的密文字节数组转为大整数,将处理好的大整数再转为字节数组。
rsa包中transform文件中提供了这两个方法:
transform.bytes2int()
transform.int2bytes()
由于RSA算法是基于“大整数运算”,因此需要将待加密的明文数据转为符合要求的大整数,其实就是在待加密数据前以某种标准的格式填充,使得填充后的新数据和RSA的密钥模长相等。
我使用了这种方式去掉前部的填充内容:final_text[final_text.index(0) + 1:]
对RSA算法原理感兴趣的可以参看以下这位大佬的博客日志:http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
关于RSA的填充问题,可以参考这位大佬的博客日志:https://blog.csdn.net/yangpl_tale/article/details/50856781