python RSA加密传输

python RSA加密传输

由于前端使用HTTP协议, 因此产生了对于数据加密的需求, 由于JS和Python中RSA秘钥产生方式的差异,踩了不少坑, 在这里记录一下.

前端
var crypt = new JSEncrypt();
crypt.setKey(__YOUR_PUBLIC_KEY__); //仅支持pkcs8标准的秘钥文件

var text = 'test';
var enc = crypt.encrypt(text);

秘钥文件格式标准

	'pkcs8标准'
# 密钥格式(公钥)
-----BEGIN PUBLIC KEY-----
# 密钥内容
-----END PUBLIC KEY-----


	'pkcs1标准'
# 密钥格式(私钥)
-----BEGIN RSA PRIVATE KEY-----
# 私钥内容
-----END RSA PRIVATE KEY-----

后端

python 后端有两个rsa加密库可用,rsa 和 PyCrytodome

安装

pip install rsa

pip install pycryptodomex

这里我使用了PyCrytodome库,rsa用法更简单明了,只是我用了以后一直和前端的rsa加密库对不上。导致前端加密过得的密文,使用这个解不开。

import base64
import os

from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5



class CryptoRsa:
    def __init__(self,password):
        self.rsa_public_key = None
        self.rsa_private_key = None
        self.password = password
    def create_rsa_key(self,password=None,path = None):
        """
        创建RSA密钥
        步骤说明:
        1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
        2、生成 1024/2048 位的 RSA 密钥
        3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
        4、将私钥写入磁盘的文件。
        5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
		
		 使用 PKCS1_v1_5,不要用 PKCS1_OAEP,PKCS1_v1_5对应的是PKCS8标准格式
 		 使用 PKCS1_OAEP 的话,前端 jsencrypt.js 只支持PKCS8,加密的数据解密不了
        """
        if not os.path.exists(path):
            os.makedirs(path)
        key = RSA.generate(1024)
        encrypted_key = key.exportKey(passphrase=password, pkcs=8,protection="scryptAndAES128-CBC")
        self.rsa_private_key = encrypted_key
        with open(path +"rsa_private_key.pem", "wb") as f:
            f.write(encrypted_key)

        self.rsa_public_key = key.publickey().exportKey()
        with open(path + "rsa_public_key.pem", "wb") as f:
            f.write(self.rsa_public_key)
    def rsa_encrypto(self,message,path=None,):
        # 加载公钥
        recipient_key = RSA.import_key(open(path + "rsa_public_key.pem").read())
        cipher_rsa = PKCS1_v1_5.new(recipient_key)
        msg = message.encode('utf8')
        en_data = cipher_rsa.encrypt(msg)

        #base64加密,方便网络传输
        bs = base64.b64encode(en_data).decode()
        return bs

    def rsa_decrypto(self,ciphertext,path =None):
        # 读取密钥
        private_key = RSA.import_key(open(path + "rsa_private_key.pem").read(), passphrase=self.password)
        cipher_rsa = PKCS1_v1_5.new(private_key)
        cipherbyte = base64.b64decode(ciphertext) #base64解码
        data = cipher_rsa.decrypt(cipherbyte, None)
        return data.decode()

if __name__ == '__main__':
    path = os.path.dirname(__file__).split('qts')[0]
    cr =  CryptoRsa(password='123456')
    res = cr.rsa_encrypto(message='wyee',path=path)
    print(res)

    str = cr.rsa_decrypto(ciphertext=res,path=path)
    print(str)

附上rsa库的用法:

import base64
import os

import rsa


class RsaCrypto:
    def __init__(self):
        self.publicKey = None
        self.privateKey = None
    def create_key(self):
        dir = os.path.dirname(__file__).split('qts')[0]
        # 生成公钥、私钥
        (self.publicKey, self.privateKey) = rsa.newkeys(1024)
        e = self.privateKey.save_pkcs1()  # 保存为 .pem 格式 (只能保存为pkcs1格式)

        with open(dir + "privateKey.pem", "wb") as x:  # 保存私钥
            x.write(e)
        f = self.publicKey.save_pkcs1()  # 保存为 .pem 格式
        with open(dir +"publicKey.pem", "wb") as x:  # 保存公钥
            x.write(f)
        return f.decode()

    def rsa_encrypt(self,str):
        # 明文编码格式
        content = str.encode("utf-8")
        # 公钥加密
        crypto = rsa.encrypt(content, self.publicKey)
        return crypto

    def rsa_decrypt(self,str):
        # 私钥解密
        content = rsa.decrypt(str, self.privateKey)
        message = content.decode("utf-8")
        return message

    def verify_sign(self,str): #验签
        str = str.encode("utf-8")
        sign = rsa.sign(str, self.privateKey, "SHA-256")  # 使用私钥进行'sha256'签名
        verify = rsa.verify(str, sign, self.publicKey)  # 使用公钥验证签名
        return verify

    def load_key(self,filepath = None,pem = None):
        if filepath:
            with open(filepath, "rb") as x:
                key = x.read()
                key = rsa.PublicKey.load_pkcs1(key)  # load 公钥,由于之前生成的私钥缺少'RSA'字段,故无法 load
        elif pem :
            key = rsa.PublicKey.load_pkcs1(pem)
        else:
            key =None
        return key
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值