由于前端使用HTTP协议, 因此产生了对于数据加密的需求, 由于JS和Python中RSA秘钥产生方式的差异,踩了不少坑, 在这里记录一下.
技术栈: JS、Python、Django、JSEncrypt
详细记录:
# 密钥格式(公钥)
-----BEGIN PUBLIC KEY-----
# 密钥内容
-----END PUBLIC KEY-----
# 密钥格式(私钥)
-----BEGIN ENCRYPTED PRIVATE KEY-----
# 私钥内容
-----END ENCRYPTED PRIVATE KEY-----
在这里不多说明如何产生密钥的了, 如有需求可以查看JSEncrypt官网.
var crypt = new JSEncrypt();
crypt.setKey(__YOUR_PUBLIC_KEY__);
var text = 'test';
var enc = crypt.encrypt(text);
在这里前端只需要导入公钥加密, 因此只写出加密的方法.
# 这里使用了装饰器 先进行解密然后传入
import base64
from functools import wraps
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5
from rest_framework.response import Response
def need_decrypt(view):
@wraps(view)
def decrypt_text(*args):
private_key = RSA.import_key(
open("private_rsa_key.bin").read(),
passphrase='test'
)
text = base64.b64decode(args[0].data['text'])
cipher_rsa = PKCS1_v1_5.new(private_key)
try:
args[0].data['text'] = cipher_rsa.decrypt(text,
None).decode()
except AttributeError:
return Response({'content': '内容错误'}, status=400)
return view(*args)
return decrypt_text
# views.py
# 这里用到了drf.
@api_view(['POST'])
@need_decrypt
def test_decrypt(request):
data = request.data.copy()
# 这里仅做样例使用 不处理数据直接返回解密结果了.
return Response({'status': 200, 'content': data},
status=200)
这样就可以实现前端加密后端解密了.