Flask框架实现的前端RSA加密与后端Python解密功能详解

系统 4786 0

本文实例讲述了Flask框架实现的前端RSA加密与后端Python解密功能。分享给大家供大家参考,具体如下:

 前言  

在使用 Flask 开发用户登录API的时候,我之前都是明文传输 username 和 password。这种传输方式有一定的安全隐患,password 可能会在传输过程中被窃听而造成用户密码的泄漏。

那么我认为解决该问题的方法是这样的:在前端页面对数据进行加密,然后再发送到后端进行处理。

这一篇文章是前端用 RSA 的 publicKey 进行加密,然后后端用 Python 进行解密的示例。

 工具列表  

  • 后端:Python3

    • Flask

    • PyCrypto(PyCrytodome)

  • 前端

    • jsencrypt.js

后端使用Cryptodome库进行密钥的生成和解密,前端则使用jsencrypt.js库进行加密。

 阅读提醒  

本文主要是提供前端RSA加密后端Python解密代码示例,不会做太详细的说明,也不会有代码打包下载链接,原理与步骤请细读示例代码或查阅相关资料。

 后端  

下面首先说明Python后端所用到的工具。

 PyCrypto和PyCrytodome  

PyCrypto 可能是 Python 中密码学方面最有名的第三方软件包。可惜的是,它的开发工作于2012年就已停止。幸运的是,有一个该项目的分支取代了 PyCrypto ,那就是 PyCrytodome。

Linux下安装命令:

pip install pycryptodome

Windows下安装命令:

pip install pycryptodomex

 PyCrytodome使用示例  

安装好 pycryptodome 后,下面放上示例代码          RSA_demo.py            。

#!/usr/bin/env python3
# coding=utf-8
# Author: yannanxiu
"""
create_rsa_key() - 创建RSA密钥
my_encrypt_and_decrypt() - 加密解密测试
"""
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5
def create_rsa_key(password="123456"):
  """
  创建RSA密钥
  步骤说明:
  1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
  2、生成 1024/2048 位的 RSA 密钥
  3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
  4、将私钥写入磁盘的文件。
  5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
  """
  key = RSA.generate(1024)
  encrypted_key = key.exportKey(passphrase=password, pkcs=8,
                 protection="scryptAndAES128-CBC")
  with open("my_private_rsa_key.bin", "wb") as f:
    f.write(encrypted_key)
  with open("my_rsa_public.pem", "wb") as f:
    f.write(key.publickey().exportKey())
def encrypt_and_decrypt_test(password="123456"):
  # 加载公钥
  recipient_key = RSA.import_key(
    open("my_rsa_public.pem").read()
  )
  cipher_rsa = PKCS1_v1_5.new(recipient_key)
  en_data = cipher_rsa.encrypt(b"123456")
  print(len(en_data), en_data)
  # 读取密钥
  private_key = RSA.import_key(
    open("my_private_rsa_key.bin").read(),
    passphrase=password
  )
  cipher_rsa = PKCS1_v1_5.new(private_key)
  data = cipher_rsa.decrypt(en_data, None)
  print(data)
if __name__ == '__main__':
  # create_rsa_key()
  encrypt_and_decrypt_test()

其中          create_rsa_key()            为创建密钥对,          encrypt_and_decrypt_test()            为加密解密的测试,用起来很简单对吧?

既然知道如何在Python端解密数据了,那么下面就是前端的代码:

 前端  

前端所用到的主要工具是          jsencrypt.js            。

 jsencrypt.js简介  

jsencrypt.js            是一个提供RSA加密、解密和密钥生成的JS库。其使用方式也非常简单。在其官网就有给出示例代码。

 Flask工程示例  

Python后端          

新建一个Python脚本,取名为          rsa_flask_demo.py            ,把下面代码复制过去。

#!/usr/bin/env python3
# coding=utf-8
# Author: yannanxiu
import os
from flask import Flask, render_template, request, current_app
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5
import base64
from urllib import parse
# 获取当前路径
curr_dir = os.path.dirname(os.path.realpath(__file__))
private_key_file = os.path.join(curr_dir, "my_private_rsa_key.bin")
public_key_file = os.path.join(curr_dir, "my_rsa_public.pem")
app = Flask(__name__)
def decrypt_data(inputdata, code="123456"):
  # URLDecode
  data = parse.unquote(inputdata)
  # base64decode
  data = base64.b64decode(data)
  private_key = RSA.import_key(
    open(curr_dir + "/my_private_rsa_key.bin").read(),
    passphrase=code
  )
  # 使用 PKCS1_v1_5,不要用 PKCS1_OAEP
  # 使用 PKCS1_OAEP 的话,前端 jsencrypt.js 加密的数据解密不了
  cipher_rsa = PKCS1_v1_5.new(private_key)
  # 当解密失败,会返回 sentinel
  sentinel = None
  ret = cipher_rsa.decrypt(data, sentinel)
  return ret
@app.route('/', methods=["GET", "POST"])
def rsa():
  public_key = None
  if "GET" == request.method:
    with open(public_key_file) as file:
      public_key = file.read()
  elif "POST" == request.method:
    username = request.values.get("username")
    password = request.values.get("passwd")
    current_app.logger.debug("username:" + username + "\n" + "password:" + password)
    # decrypt
    username_ret = decrypt_data(username)
    password_ret = decrypt_data(password)
    if username_ret and password_ret:
      current_app.logger.debug(username_ret.decode() + " " + password_ret.decode())
  return render_template("rsa_view.html", public_key=public_key)
@app.route('/js_rsa_test', methods=["GET", "POST"])
def js_rsa_test():
  return render_template("js_rsa_test.html")
if __name__ == '__main__':
  app.run(debug=True)

把          rsa_flask_demo.py            与前面的          RSA_demo.py            脚本放在一起,再用          RSA_demo.py            生成一组密钥对。或者把前面生成密钥对文件放在同一个目录下也可以。

前端代码          

在同一目录下新建一个templates文件夹,用来存放Flask的前端模板。

在templates文件夹新建          rsa_view.html            ,并拷贝下面代码过去,该HTML文件与Flask中的          rsa()            相对应。

[object Object]

运行          rsa_flask_demo.py            ,访问          http://127.0.0.1:5000/            ,即可看到下面页面。直接点击submit按钮即可。

张军博客

当后台页面打印:

--------------------------------------------------------------------------------
DEBUG in rsa_flask_demo [F:/Flask/RSA_Flask/rsa_flask_demo.py:57]:
user 123
--------------------------------------------------------------------------------

即说明解密成功!

其他          

rsa_flask_demo.py            中的          js_rsa_test()            为JS脚本测试页面,其对应的HTML代码如下:

[object Object]

启动服务后访问          http://127.0.0.1:5000/js_rsa_test            即可。代码内容主要是先用          jsencrypt.js            加密数据,再进行解密,如果成功则弹出It works!!!对话框。不传输数据到后台,仅仅作为前端测试。

目录结构          

│  my_private_rsa_key.bin
│  my_rsa_public.pem
│  RSA_demo.py
│  rsa_flask_demo.py

└─templates
        js_rsa_test.html
        rsa_view.html

 PS:关于加密解密感兴趣的朋友还可以参考本站在线工具:  

 在线RSA加密/解密工具:              
 
 http://tools.jb51.net/password/rsa_encode          

 文字在线加密解密工具(包含AES、DES、RC4等):              
http://tools.jb51.net/password/txt_encode          

 MD5在线加密工具:              
 
 http://tools.jb51.net/password/CreateMD5Password

 在线散列/哈希算法加密工具:              
 
 http://tools.jb51.net/password/hash_encrypt

 在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:              
 
 http://tools.jb51.net/password/hash_md5_sha

 在线sha1/sha224/sha256/sha384/sha512加密工具:              
 
 http://tools.jb51.net/password/sha_encode

希望本文所述对大家基于flask框架的Python程序设计有所帮助。

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论