最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask框架實(shí)現(xiàn)的前端RSA加密與后端Python解密功能詳解

 更新時(shí)間:2019年08月13日 12:01:27   作者:閼男秀  
這篇文章主要介紹了Flask框架實(shí)現(xiàn)的前端RSA加密與后端Python解密功能,結(jié)合實(shí)例形式詳細(xì)分析了flask框架前端使用jsencrypt.js加密與后端Python解密相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Flask框架實(shí)現(xiàn)的前端RSA加密與后端Python解密功能。分享給大家供大家參考,具體如下:

前言

在使用 Flask 開(kāi)發(fā)用戶登錄API的時(shí)候,我之前都是明文傳輸 username 和 password。這種傳輸方式有一定的安全隱患,password 可能會(huì)在傳輸過(guò)程中被竊聽(tīng)而造成用戶密碼的泄漏。

那么我認(rèn)為解決該問(wèn)題的方法是這樣的:在前端頁(yè)面對(duì)數(shù)據(jù)進(jìn)行加密,然后再發(fā)送到后端進(jìn)行處理。

這一篇文章是前端用 RSA 的 publicKey 進(jìn)行加密,然后后端用 Python 進(jìn)行解密的示例。

工具列表

  • 后端:Python3
    • Flask
    • PyCrypto(PyCrytodome)
  • 前端

后端使用Cryptodome庫(kù)進(jìn)行密鑰的生成和解密,前端則使用jsencrypt.js庫(kù)進(jìn)行加密。

閱讀提醒

本文主要是提供前端RSA加密后端Python解密代碼示例,不會(huì)做太詳細(xì)的說(shuō)明,也不會(huì)有代碼打包下載鏈接,原理與步驟請(qǐng)細(xì)讀示例代碼或查閱相關(guān)資料。

后端

下面首先說(shuō)明Python后端所用到的工具。

PyCrypto和PyCrytodome

PyCrypto 可能是 Python 中密碼學(xué)方面最有名的第三方軟件包??上У氖?,它的開(kāi)發(fā)工作于2012年就已停止。幸運(yùn)的是,有一個(gè)該項(xiàng)目的分支取代了 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() - 創(chuàng)建RSA密鑰
my_encrypt_and_decrypt() - 加密解密測(cè)試
"""
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5
def create_rsa_key(password="123456"):
  """
  創(chuàng)建RSA密鑰
  步驟說(shuō)明:
  1、從 Crypto.PublicKey 包中導(dǎo)入 RSA,創(chuàng)建一個(gè)密碼
  2、生成 1024/2048 位的 RSA 密鑰
  3、調(diào)用 RSA 密鑰實(shí)例的 exportKey 方法,傳入密碼、使用的 PKCS 標(biāo)準(zhǔn)以及加密方案這三個(gè)參數(shù)。
  4、將私鑰寫入磁盤的文件。
  5、使用方法鏈調(diào)用 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()為創(chuàng)建密鑰對(duì),encrypt_and_decrypt_test()為加密解密的測(cè)試,用起來(lái)很簡(jiǎn)單對(duì)吧?

既然知道如何在Python端解密數(shù)據(jù)了,那么下面就是前端的代碼:

前端

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

jsencrypt.js簡(jiǎn)介

jsencrypt.js是一個(gè)提供RSA加密、解密和密鑰生成的JS庫(kù)。其使用方式也非常簡(jiǎn)單。在其官網(wǎng)就有給出示例代碼。

Flask工程示例

Python后端

新建一個(gè)Python腳本,取名為rsa_flask_demo.py,把下面代碼復(fù)制過(guò)去。

#!/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
# 獲取當(dāng)前路徑
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 加密的數(shù)據(jù)解密不了
  cipher_rsa = PKCS1_v1_5.new(private_key)
  # 當(dāng)解密失敗,會(huì)返回 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生成一組密鑰對(duì)?;蛘甙亚懊嫔擅荑€對(duì)文件放在同一個(gè)目錄下也可以。

前端代碼

在同一目錄下新建一個(gè)templates文件夾,用來(lái)存放Flask的前端模板。

在templates文件夾新建rsa_view.html,并拷貝下面代碼過(guò)去,該HTML文件與Flask中的rsa()相對(duì)應(yīng)。

<!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類庫(kù)加密js方法,
    function encryptRequest(reqUrl, data, publicKey) {
      var encrypt = new JSEncrypt();
      encrypt.setPublicKey(publicKey);
      // ajax請(qǐng)求發(fā)送的數(shù)據(jù)對(duì)象
      var sendData = new Object();
      // 將data數(shù)組賦給ajax對(duì)象
      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('出錯(cuò)了');
        }
      });
    }
    // 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>

運(yùn)行rsa_flask_demo.py,訪問(wèn)http://127.0.0.1:5000/,即可看到下面頁(yè)面。直接點(diǎn)擊submit按鈕即可。

當(dāng)后臺(tái)頁(yè)面打印:

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

即說(shuō)明解密成功!

其他

rsa_flask_demo.py中的js_rsa_test()為JS腳本測(cè)試頁(yè)面,其對(duì)應(yīng)的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>

啟動(dòng)服務(wù)后訪問(wèn)http://127.0.0.1:5000/js_rsa_test即可。代碼內(nèi)容主要是先用jsencrypt.js加密數(shù)據(jù),再進(jìn)行解密,如果成功則彈出It works!!!對(duì)話框。不傳輸數(shù)據(jù)到后臺(tái),僅僅作為前端測(cè)試。

目錄結(jié)構(gòu)

│  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:關(guān)于加密解密感興趣的朋友還可以參考本站在線工具:

在線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

希望本文所述對(duì)大家基于flask框架的Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Python驗(yàn)證的50個(gè)常見(jiàn)正則表達(dá)式

    Python驗(yàn)證的50個(gè)常見(jiàn)正則表達(dá)式

    這篇文章主要給大家介紹了關(guān)于利用Python驗(yàn)證的50個(gè)常見(jiàn)正則表達(dá)式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • python執(zhí)行子進(jìn)程實(shí)現(xiàn)進(jìn)程間通信的方法

    python執(zhí)行子進(jìn)程實(shí)現(xiàn)進(jìn)程間通信的方法

    這篇文章主要介紹了python執(zhí)行子進(jìn)程實(shí)現(xiàn)進(jìn)程間通信的方法,涉及Python使用subprocess模塊操作進(jìn)程的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • Python調(diào)用Tkinter示例淺析

    Python調(diào)用Tkinter示例淺析

    這篇文章主要介紹了Python調(diào)用Tkinter示例,通過(guò)在Python程序中設(shè)計(jì)按鈕,可以方便用戶調(diào)用Python程序,從而達(dá)到快速、自動(dòng)化、高效的目的,提高用戶體驗(yàn)和工作效率
    2023-02-02
  • Python連續(xù)賦值需要注意的一些問(wèn)題

    Python連續(xù)賦值需要注意的一些問(wèn)題

    這篇文章主要介紹了Python連續(xù)賦值需要注意的一些問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 詳解Python中四種關(guān)系圖數(shù)據(jù)可視化的效果對(duì)比

    詳解Python中四種關(guān)系圖數(shù)據(jù)可視化的效果對(duì)比

    python關(guān)系圖的可視化主要就是用來(lái)分析一堆數(shù)據(jù)中,每一條數(shù)據(jù)的節(jié)點(diǎn)之間的連接關(guān)系從而更好的分析出人物或其他場(chǎng)景中存在的關(guān)聯(lián)關(guān)系。本文將制作四個(gè)不同的關(guān)系圖的可視化效果,感興趣的可以了解一下
    2022-11-11
  • pytorch 指定gpu訓(xùn)練與多gpu并行訓(xùn)練示例

    pytorch 指定gpu訓(xùn)練與多gpu并行訓(xùn)練示例

    今天小編就為大家分享一篇pytorch 指定gpu訓(xùn)練與多gpu并行訓(xùn)練示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • 教你用python控制安卓手機(jī)

    教你用python控制安卓手機(jī)

    不久前,我在思考如何通過(guò)向好友發(fā)送幾分鐘的垃圾郵件來(lái)惹惱我的朋友,而在做一些研究的過(guò)程中,我遇到了Android調(diào)試橋.在本快速指南中,我將向您展示如何使用Python與之交互以及如何創(chuàng)建2個(gè)快速腳本.需要的朋友可以參考下
    2021-05-05
  • Python中關(guān)于property使用的小技巧

    Python中關(guān)于property使用的小技巧

    俗話說(shuō)條條大路通羅馬,同樣是完成一件事,Python 其實(shí)提供了好幾個(gè)方式供你選擇。property() 是一個(gè)比較奇葩的BIF,它的作用把方法當(dāng)作屬性來(lái)訪問(wèn),從而提供更加友好訪問(wèn)方式
    2021-09-09
  • Python實(shí)現(xiàn)下雪效果的示例代碼

    Python實(shí)現(xiàn)下雪效果的示例代碼

    turtle是Python編程語(yǔ)言中的一個(gè)模塊,用于繪制圖形和圖形動(dòng)畫,本文主要為大家詳細(xì)介紹了Python如何使用turtle實(shí)現(xiàn)張萬(wàn)森下雪了的效果,感興趣的可以了解下
    2023-12-12
  • Python異常的檢測(cè)和處理方法

    Python異常的檢測(cè)和處理方法

    今天小編就為大家分享一篇關(guān)于Python異常的檢測(cè)和處理方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10

最新評(píng)論

陆川县| 襄城县| 临颍县| 津市市| 体育| 泰顺县| 女性| 剑川县| 正宁县| 三台县| 河北省| 绍兴市| 获嘉县| 合山市| 加查县| 临朐县| 福鼎市| 南城县| 修水县| 古田县| 岱山县| 牙克石市| 灵宝市| 天台县| 广平县| 汽车| 祥云县| 兴山县| 呼伦贝尔市| 齐河县| 海兴县| 文昌市| 辰溪县| 凤翔县| 远安县| 浮梁县| 温宿县| 偃师市| 彭州市| 闻喜县| 吉安市|