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

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

前言

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

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

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

工具列表

  • 后端:Python3

    • Flask
    • PyCrypto(PyCrytodome)
  • 前端

后端使用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()相对应。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
  <script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
  <script type="text/javascript">
    // 使用jsencrypt类库加密js方法,
    function encryptRequest(reqUrl, data, publicKey) {
      var encrypt = new JSEncrypt();
      encrypt.setPublicKey(publicKey);
      // ajax请求发送的数据对象
      var sendData = new Object();
      // 将data数组赋给ajax对象
      for (var key in data) {
        sendData[key] = encrypt.encrypt(data[key]);
      }
      console.info(sendData);
      $.ajax({
        url: reqUrl,
        type: 'post',
        data: sendData,
        dataType: 'json',
        //contentType: 'application/json; charset=utf-8',
        success: function (data) {
          console.info(data);
        },
        error: function (xhr) {
          //console.error('出错了');
        }
      });
    }
    // Call this code when the page is done loading.
    $(function () {
      $('#testme').click(function () {
        var data = [];
        data['username'] = $('#username').val();
        data['passwd'] = $('#passwd').val();
        var pkey = $('#pubkey').val();
        encryptRequest('/', data, pkey);
      });
    });
  </script>
</head>
<body>
<form id="form1" runat="server">
  <div>
    <label for="pubkey">Public Key</label><br/>
    <textarea id="pubkey" rows="15" cols="65">
        {{ public_key }}
      </textarea><br/>
    <label for="input">Text to encrypt:</label><br/>
    name:<input id="username" name="username" type="text" value="user"></input><br/>
    password:<input id="passwd" name="passwd" type="password" value="123"></input><br/>
    <input id="testme" type="button" value="submit"/><br/>
  </div>
</form>
</body>
</html>

运行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代码如下:

<!doctype html>
<html>
 <head>
  <title>JavaScript RSA Encryption</title>
  <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
  <script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
  <script type="text/javascript">
   // Call this code when the page is done loading.
   $(function() {
    // Run a quick encryption/decryption when they click.
    $('#testme').click(function() {
     // Encrypt with the public key...
     var encrypt = new JSEncrypt();
     encrypt.setPublicKey($('#pubkey').val());
     var encrypted = encrypt.encrypt($('#input').val());
     // Decrypt with the private key...
     var decrypt = new JSEncrypt();
     decrypt.setPrivateKey($('#privkey').val());
     var uncrypted = decrypt.decrypt(encrypted);
     // Now a simple check to see if the round-trip worked.
     if (uncrypted == $('#input').val()) {
      alert('It works!!!');
     }
     else {
      alert('Something went wrong....');
     }
    });
   });
  </script>
 </head>
 <body>
  <label for="privkey">Private Key</label><br/>
  <textarea id="privkey" rows="15" cols="65">-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876
-----END RSA PRIVATE KEY-----</textarea><br/>
  <label for="pubkey">Public Key</label><br/>
  <textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
gwQco1KRMDSmXSMkDwIDAQAB
-----END PUBLIC KEY-----</textarea><br/>
  <label for="input">Text to encrypt:</label><br/>
  <textarea id="input" name="input" type="text" rows=4 cols=70>This is a test!</textarea><br/>
  <input id="testme" type="button" value="Test Me!!!" /><br/>
 </body>
</html>

启动服务后访问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程序设计有所帮助。

(0)

相关推荐

  • python使用rsa加密算法模块模拟新浪微博登录

    PC登录新浪微博时,在客户端用js预先对用户名.密码都进行了加密,而且在POST之前会GET一组参数,这也将作为POST_DATA的一部分.这样,就不能用通常的那种简单方法来模拟POST登录(比如人人网). 通过爬虫获取新浪微博数据,模拟登录是必不可少的. 1.在提交POST请求之前,需要GET获取四个参数(servertime,nonce,pubkey和rsakv),不是之前提到的只是获取简单的servertime,nonce,这里主要是由于js对用户名.密码加密方式改变了. 1.1 由于加密

  • python实现rsa加密实例详解

    python实现rsa加密实例详解 一 代码 import rsa key = rsa.newkeys(3000)#生成随机秘钥 privateKey = key[1]#私钥 publicKey = key[0]#公钥 message ='sanxi Now is better than never.' print('Before encrypted:',message) message = message.encode() cryptedMessage = rsa.encrypt(messag

  • Python使用Pycrypto库进行RSA加密的方法详解

    密码与通信 密码技术是一门历史悠久的技术.信息传播离不开加密与解密.密码技术的用途主要源于两个方面,加密/解密和签名/验签 在信息传播中,通常有发送者,接受者和窃听者三个角色.假设发送者Master想要写信给接受者Ghost,可是又不想信的内容被别人看到,因此Master需要先对信加密,而Ghost收到信之后又能解密.这样别的人即使窃听盗取了密文也无法解密.其次,如果窃听者并不像破译内容,而是伪造Master发消息给Ghost,那么Master发消息前就得先对机密内容进行签名. 密码技术 为了进

  • Python实现的rsa加密算法详解

    本文实例讲述了Python实现的rsa加密算法.分享给大家供大家参考,具体如下: 算法过程 1. 随意选择两个大的质数p和q,p不等于q,计算N=pq. 2. 根据欧拉函数,不大于N且与N互质的整数個数為(p-1)(q-1). 3. 选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1). 4. 用以下这个公式计算d:d× e ≡ 1 (mod (p-1)(q-1)). 5. 将p和q的记录销毁. (N,e)是公钥,(N,d)是私钥. python代码 # -*- coding

  • Python下实现的RSA加密/解密及签名/验证功能示例

    本文实例讲述了Python下实现的RSA加密/解密及签名/验证功能.分享给大家供大家参考,具体如下: 原文是py2环境,而我的环境是py3,所以对原代码做了修改:decode(), encode() import rsa # 生成密钥 (pubkey, privkey) = rsa.newkeys(1024) # 保存密钥 with open('public.pem','w+') as f: f.write(pubkey.save_pkcs1().decode()) with open('pri

  • python rsa 加密解密

    最近有需求,需要研究一下RSA加密解密安全:在网上百度了一下例子文章,很少有文章介绍怎么保存.传输.打印加密后的文本信息,都是千篇一律的.直接在一个脚本,加密后的文本信息赋于变量,然后立马调用解密.仔细想了一下RSA加密解密的过程,确定有二端,一端为:加密端,一端为解密端,一般不在同一台机器.在这里,我只模拟了保存在文件,然后再读出来:关于怎以通过网络传输,也是大同小异. 用RSA加密后的密文,是无法直接用文本显示,因为存在一些无法用文本信息编码显示的二进制数据.对于保存,网络传输,打印不乱码,

  • python实现RSA加密(解密)算法

    RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准. 今天只有短的RSA钥匙才可能被强力方式解破.到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式.只要其密钥的长度足够长,用RSA加密的信息实际上是不能被解破的.但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战. RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥.

  • Python3非对称加密算法RSA实例详解

    本文实例讲述了Python3非对称加密算法RSA.分享给大家供大家参考,具体如下: python3 可以使用 Crypto.PublicKey.RSA 和 rsa 生成公钥.私钥. 其中 python3.6 Crypto 库的安装方式请参考前面一篇<Python3对称加密算法AES.DES3> rsa 加解密的库使用 pip3 install rsa 就行了 C:\WINDOWS\system32>pip3 install rsa Collecting rsa   Downloading

  • Flask框架中密码的加盐哈希加密和验证功能的用法详解

    密码加密简介 密码存储的主要形式: 明文存储:肉眼就可以识别,没有任何安全性. 加密存储:通过一定的变换形式,使得密码原文不易被识别. 密码加密的几类方式: 明文转码加密:BASE64, 7BIT等,这种方式只是个障眼法,不是真正的加密. 对称算法加密:DES, RSA等. 签名算法加密:也可以理解为单向哈希加密,比如MD5, SHA1等.加密算法固定,容 易被暴力破解.如果密码相同,得到的哈希值是一样的. 加盐哈希加密:加密时混入一段"随机"字符串(盐值)再进行哈希加密.即使密码相同

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

    本文实例讲述了Flask框架实现的前端RSA加密与后端Python解密功能.分享给大家供大家参考,具体如下: 前言 在使用 Flask 开发用户登录API的时候,我之前都是明文传输 username 和 password.这种传输方式有一定的安全隐患,password 可能会在传输过程中被窃听而造成用户密码的泄漏. 那么我认为解决该问题的方法是这样的:在前端页面对数据进行加密,然后再发送到后端进行处理. 这一篇文章是前端用 RSA 的 publicKey 进行加密,然后后端用 Python 进行

  • jQuery实现base64前台加密解密功能详解

    本文实例讲述了jQuery实现base64前台加密解密功能.分享给大家供大家参考,具体如下: 关于加密,很多人想到encodeURI和escape.这个对加密url,尤其是带中文参数的url很有用. 如果只是想做加密解密,类似于Java的DES,网上jQuery有个jquery.base64.js. (关于js的md5加密可以用jquery.md5.js,有兴趣可以找来测试一下). 下面是测试: <html> <head> <title></title> &

  • java基于Des对称加密算法实现的加密与解密功能详解

    本文实例讲述了java基于Des对称加密算法实现的加密与解密功能.分享给大家供大家参考,具体如下: Des 加密相关类介绍: SecureRandom  这个类是继承自java.util.Random 这个类 SecureRandom 这个类的构造器有三种,下面例举两种: SecureRandom()构造一个实现默认随机数算法的安全随机数生成器 (RNG). SecureRandom(byte[] seed)构造一个实现默认随机数算法的安全随机数生成器 (RNG). DESKeySpec 这个类

  • Vue前端如何实现生成PDF并下载功能详解

    目录 1. 安装及引入 2. 封装导出 pdf 文件方法 配置详解 封装导出 pdf 文件方法(utils/htmlToPdf.js) 相关组件中应用 效果 待优化部分 总结 思路: 通过 html2canvas 将 HTML 页面转换成图片,然后再通过 jspdf 将图片的 base64 生成为 pdf 文件. 1. 安装及引入 // 将页面 html 转换成图片 npm install html2canvas --save // 将图片生成 pdf npm install jspdf --s

  • 前端加密cryptojs与JSEncrypt使实例详解

    目录 单向散列函数 MD5 简单介绍 使用场景 使用 crypto-js 进行 MD5 加密 CryptoJS.MD5() algo 对称加密算法 AES 使用 crypto-js 进行 AES 加密 解密 非对称加密RSA 使用 JSEncrypt 进行 RSA 加密 使用 JSEncrypt 进行 RSA 解密 OpenSSL 安装 生成私钥 生成公钥 单向散列函数 在网站项目中,有时我们需要对传给后端的数据,比如 token 等进行加密处理.本文是对几种常见的前端加密方法,以及如何使用开源

  • RSA加密的方式和解密方式实现方法(推荐)

    RSAsecurity.java package com.mstf.rsa; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKe

  • java使用RSA加密方式实现数据加密解密的代码

    RSA的应用 RSA是一种非对称加密算法.现在,很多登陆表单的密码的都采用RSA加密,例如京东中的登陆使用公钥对密码进行加密 java使用RSA加密方式实现数据加密解密,需要首先产生私钥和公钥 测试代码 public static void main(String args[]) { try { RSADemo rsa=new RSADemo(); rsa.generateKey(); byte[] data=rsa.encrypt("luanpeng".getBytes()); by

  • MySQL加密和解密实例详解

    MySQL加密和解密实例详解 数据加密.解密在安全领域非常重要.对程序员而言,在数据库中以密文方式存储用户密码对入侵者剽窃用户隐私意义重大. 有多种前端加密算法可用于数据加密.解密,下面我向您推荐一种简单的数据库级别的数据加密.解密解决方案.以MySQL数据库为例,它内建了相应的加密函数(AES_ENCRYPT() )和解密函数(AES_DECRYPT()). 在建表的时候,要注意字段的类型.如下图所示: 在表中插入加密数据 上面的插入语句有三个字段,"用户名"."密码&qu

  • NodeJS加密解密及node-rsa加密解密用法详解

    要用nodejs开发接口,实现远程调用,如果裸奔太危险了,就在网上找了一下nodejs的加密,感觉node-rsa挺不错的,下面来总结一下简单的rsa加密解密用法 初始化环境 新建一个文件夹 node-rsa-demo , 终端进入,运行下面命令初始化 cd node-rsa-demo npm init # 一路回车即可 npm install --save node-rsa 生成公钥私钥 在 node-rsa-demo 下新建一个文件 index.js 写上如下代码 var NodeRSA =

  • springboot实现注册的加密与登录的解密功能(demo)

    前情提要:本demo是基于springboot+mybatis-plus实现加密,加密为主,全局异常处理,日志处理为辅,而登录密码加密是每个项目中必须要的,密码不可能明文存入数据,这样没有安全性. 涉及的功能,全局异常处理,日志处理,mybatis-plus实现与数据库的交互,密码加密,restful风格 涉及的工具:IDEA,postman,sqlyog(navicat) 1. 首先我们直接看效果吧,如果你不满意,也就没必要看了 如果这正是你想要的效果呢,那你可以继续看下面的内容了 2. 首先

随机推荐