本文實(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)
前端
jsencrypt.js
后端使用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、將私鑰寫(xiě)入磁盤(pán)的文件。 5、使用方法鏈調(diào)用 publickey 和 exportKey 方法生成公鑰,寫(xiě)入磁盤(pán)上的文件。 """ 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)。
[object Object]
運(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代碼如下:
[object Object]
啟動(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ì)有所幫助。
本文為張軍原創(chuàng)文章,轉(zhuǎn)載無(wú)需和我聯(lián)系,但請(qǐng)注明來(lái)自張軍的軍軍小站,個(gè)人博客http://www.eyofj.com
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
