hunter-ji / Blog

My Blog.
121 stars 38 forks source link

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

Open hunter-ji opened 4 years ago

hunter-ji commented 4 years ago

一. 介绍

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

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

二. 环境

三. 后端生成密钥

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 RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto import Random
from 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)

六. 完整代码

前端

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 RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto import Random
from 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;
}