vlambda博客
学习文章列表

vue+flask前后端信息传输非对称加密


一. 介绍

为了前后端传输数据的安全性,需要对数据进行加密。因此选定使用非对称加密,此处为RSA。


在传输数据前,后端生成公钥和私钥,将公钥给前端,前端加密之后,将密文传给后端,后端使用私钥解密即可得到原始的数据。




二. 环境

前端使用jsencrypt加密

后端使用Crypto生成密钥和解密




三. 后端生成密钥


from Crypto.PublicKey import RSA

def generate_key(): """ 生成公钥和私钥 :return: 返回私钥和公钥 """ rsa = RSA.generate(1024) private_key = rsa.exportKey() publick_key = rsa.publickey().exportKey() return private_key.decode(), publick_key.decode()




四. 前端用公钥加密


import { JSEncrypt } from "jsencrypt";

function rsa_en(pubkey, target_str) { /** 分段加密信息 :params target_str: 需要加密的信息,此处为很长的信息 :pubkey: 公钥 :return: 存储密文的数组 **/ let encrypt = new JSEncrypt(); encrypt.setPublicKey(pubkey); let result = encrypt.encrypt(JSON.stringify(target_str));}





五. 后端使用私钥解密


from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5from Crypto.Hash import SHAfrom Crypto import Randomfrom base64 import b64decode

def rsa_decrypt(private_key, message): """ rsa解密函数
:prams private_key: 私钥 :params message: 加密后的密文 :return: 解密后原始信息 """ dsize = SHA.digest_size sentinel = Random.new().read(1024 + dsize) private_key = RSA.import_key(private_key) cipher_rsa = PKCS1_v1_5.new(private_key) return cipher_rsa.decrypt(b64decode(message), sentinel)


这里使用base64先解密一遍是必要的,否则报错ValueError: Ciphertext with incorrect length.




六. 完整代码

前端


import { JSEncrypt } from "jsencrypt";

function rsa_en(pubkey, target_str) { /** 分段加密信息 :params target_str: 需要加密的信息,此处为很长的信息 :pubkey: 公钥 :return: 存储密文的数组 **/ let encrypt = new JSEncrypt(); encrypt.setPublicKey(pubkey); let result = encrypt.encrypt(JSON.stringify(target_str));}


后端


from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5from Crypto.Hash import SHAfrom Crypto import Randomfrom base64 import b64decode

def generate_key(): """ 生成公钥和私钥
:return: 返回私钥和公钥 """ rsa = RSA.generate(1024) private_key = rsa.exportKey() publick_key = rsa.publickey().exportKey()    return private_key.decode(), publick_key.decode()
def rsa_encrypt(public_key, message): """ rsa加密函数
    :params publick_key: 公钥 :params message: 需要加密的信息 :return: 加密后的密文 """ public_key = RSA.import_key(public_key) cipher_rsa = PKCS1_v1_5.new(public_key) return cipher_rsa.encrypt(str.encode(message))
def rsa_decrypt(private_key, message): """ rsa解密函数
:prams private_key: 私钥 :params message: 加密后的密文 :return: 解密后原始信息 """ dsize = SHA.digest_size sentinel = Random.new().read(1024 + dsize) private_key = RSA.import_key(private_key) cipher_rsa = PKCS1_v1_5.new(private_key) return cipher_rsa.decrypt(b64decode(message), sentinel)




七. 分段加密

RSA加密信息最长为128位,过长则会报错,因此,对于过长的信息需要分段加密,后端也要分段解密后拼装。


import { JSEncrypt } from "jsencrypt";
function en_str(target_str, pubkey) { /** 分段加密信息 :params target_str: 需要加密的信息,此处为很长的信息 :pubkey: 公钥 :return: 存储密文的数组 **/ let encrypt = new JSEncrypt(); encrypt.setPublicKey(pubkey); let en_array = []; let n = 100; // 每段信息的长度 for (let i = 0, l = target_str.length; i < l / n; i++) { let message = target_str.slice(n * i, n * (i + 1)); en_array.push(encrypt.encrypt(message)); } return en_array;}