正在显示
5 个修改的文件
包含
78 行增加
和
42 行删除
@@ -5,31 +5,48 @@ from flask_sqlalchemy import SQLAlchemy | @@ -5,31 +5,48 @@ from flask_sqlalchemy import SQLAlchemy | ||
5 | import glob | 5 | import glob |
6 | import traceback | 6 | import traceback |
7 | from pyDes import des, PAD_PKCS5, ECB | 7 | from pyDes import des, PAD_PKCS5, ECB |
8 | - | 8 | +import json |
9 | import base64 | 9 | import base64 |
10 | -from gmssl import sm3, func, sm2 | 10 | +from gmssl import sm3, func |
11 | +from Crypto.Cipher import AES | ||
12 | +from Crypto.Util.Padding import unpad, pad | ||
13 | +from cryptography.hazmat.primitives import padding | ||
14 | +from cryptography.hazmat.primitives.ciphers import algorithms | ||
15 | +from binascii import b2a_hex, a2b_hex | ||
11 | 16 | ||
12 | 17 | ||
13 | -class SM3(): | 18 | +class AESHelper(): |
19 | + key = 'w03MyIgc3zMHM5Qe'.encode('utf-8') | ||
20 | + iv = '8765432187654321'.encode('utf-8') | ||
21 | + | ||
14 | @classmethod | 22 | @classmethod |
15 | - def encode(self, data=""): | ||
16 | - by_str = bytes(data, 'utf-8') | ||
17 | - result = (sm3.sm3_hash(func.bytes_to_list(by_str))) | ||
18 | - return result | 23 | + def encode(self, instr): |
24 | + plaintxt = self._pad(instr) | ||
25 | + aes = AES.new(self.key, AES.MODE_CBC, self.iv) | ||
26 | + ciphertext = aes.encrypt(plaintxt) | ||
27 | + return b2a_hex(ciphertext).decode('utf-8') | ||
19 | 28 | ||
29 | + @classmethod | ||
30 | + def decode(self, instr): | ||
31 | + encryptedData = instr | ||
32 | + aes = AES.new(self.key, AES.MODE_CBC, self.iv) | ||
33 | + plaintxt = aes.decrypt(a2b_hex(encryptedData)) | ||
34 | + return bytes.decode(unpad(plaintxt, AES.block_size)) | ||
20 | 35 | ||
21 | -class SM2(): | ||
22 | - privatekey = "EOpBYj1pH54b8BsAlkON71Q2c2FXEm+VTPNCgxz4+gVZ2C/pF/Bv152Qj3QH7cBRCUlNeO5SkI02DcwTASmVwESzR4F9IbMvUNxkDngINdcwaSWCTaaRTstNd4FIlJ0CqhDl/TPHFuBoRNBgUDfPJFfl7XYHs4VmOcrp02aXv8Q=" | ||
23 | - publickey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEsENe/8Sft6rK0h59t2a/6Pf4nzvxvJzc1SzalZe1xSDtUqW/10E/e+RjRbvykyjKzu3vAY1lwv9aU2Tnp6+isw==" | ||
24 | - sm2_crypt = sm2.CryptSM2(public_key=publickey, private_key=privatekey) | 36 | + def _pad(data): |
37 | + if not isinstance(data, bytes): | ||
38 | + data = data.encode() | ||
39 | + padder = padding.PKCS7(algorithms.AES.block_size).padder() | ||
40 | + padded_data = padder.update(data)+padder.finalize() | ||
41 | + return padded_data | ||
25 | 42 | ||
26 | - @classmethod | ||
27 | - def decode(self, ciphertxt): | ||
28 | - return self.sm2_crypt.decrypt(ciphertxt) | ||
29 | 43 | ||
44 | +class SM3(): | ||
30 | @classmethod | 45 | @classmethod |
31 | - def encode(self, plaintxt): | ||
32 | - return self.sm2_crypt.encrypt(plaintxt) | 46 | + def encode(self, data=""): |
47 | + by_str = bytes(data, 'utf-8') | ||
48 | + result = sm3.sm3_hash(func.bytes_to_list(by_str)) | ||
49 | + return result | ||
33 | 50 | ||
34 | 51 | ||
35 | class DES(): | 52 | class DES(): |
1 | from enum import auto | 1 | from enum import auto |
2 | from logging import error | 2 | from logging import error |
3 | +from unittest import result | ||
3 | from flasgger import swag_from | 4 | from flasgger import swag_from |
4 | from app.util import BlueprintApi | 5 | from app.util import BlueprintApi |
5 | from app.util import BlueprintApi | 6 | from app.util import BlueprintApi |
6 | from flask import Blueprint, render_template, redirect, request, session, jsonify | 7 | from flask import Blueprint, render_template, redirect, request, session, jsonify |
7 | from .models import * | 8 | from .models import * |
8 | -from .oauth2 import authorization, generate_user_info,require_oauth | 9 | +from .oauth2 import authorization, generate_user_info, require_oauth |
9 | from authlib.oauth2 import OAuth2Error | 10 | from authlib.oauth2 import OAuth2Error |
10 | from authlib.integrations.flask_oauth2 import current_token | 11 | from authlib.integrations.flask_oauth2 import current_token |
11 | from . import user_create, client_create, client_query, user_query, user_update, user_delete | 12 | from . import user_create, client_create, client_query, user_query, user_update, user_delete |
12 | import configure | 13 | import configure |
13 | from app.decorators.auth_decorator import auth_decorator | 14 | from app.decorators.auth_decorator import auth_decorator |
14 | import time | 15 | import time |
15 | -from app.models import SM3 | 16 | +from app.models import SM3, AESHelper |
17 | + | ||
16 | 18 | ||
17 | def current_user(): | 19 | def current_user(): |
18 | if "id" in session: | 20 | if "id" in session: |
@@ -71,8 +73,6 @@ class DataManager(BlueprintApi): | @@ -71,8 +73,6 @@ class DataManager(BlueprintApi): | ||
71 | return jsonify(dict(error.get_body())) | 73 | return jsonify(dict(error.get_body())) |
72 | return render_template("auth/authorize.html", user=user, grant=grant, error=error) | 74 | return render_template("auth/authorize.html", user=user, grant=grant, error=error) |
73 | 75 | ||
74 | - | ||
75 | - | ||
76 | @staticmethod | 76 | @staticmethod |
77 | @bp.route("/token", methods=["POST"]) | 77 | @bp.route("/token", methods=["POST"]) |
78 | def issue_token(): | 78 | def issue_token(): |
@@ -105,8 +105,7 @@ class DataManager(BlueprintApi): | @@ -105,8 +105,7 @@ class DataManager(BlueprintApi): | ||
105 | except OAuth2Error as error: | 105 | except OAuth2Error as error: |
106 | return jsonify(dict(error.get_body())) | 106 | return jsonify(dict(error.get_body())) |
107 | return redirect(url) | 107 | return redirect(url) |
108 | - | ||
109 | - | 108 | + |
110 | """接口""" | 109 | """接口""" |
111 | @staticmethod | 110 | @staticmethod |
112 | @bp.route("/users", methods=["GET"]) | 111 | @bp.route("/users", methods=["GET"]) |
@@ -165,7 +164,7 @@ class DataManager(BlueprintApi): | @@ -165,7 +164,7 @@ class DataManager(BlueprintApi): | ||
165 | 获取client列表 | 164 | 获取client列表 |
166 | """ | 165 | """ |
167 | return client_query.Api().result | 166 | return client_query.Api().result |
168 | - | 167 | + |
169 | @staticmethod | 168 | @staticmethod |
170 | @bp.route("/init", methods=["GET"]) | 169 | @bp.route("/init", methods=["GET"]) |
171 | def init(): | 170 | def init(): |
@@ -183,3 +182,11 @@ class DataManager(BlueprintApi): | @@ -183,3 +182,11 @@ class DataManager(BlueprintApi): | ||
183 | else: | 182 | else: |
184 | return "默认用户已存在" | 183 | return "默认用户已存在" |
185 | 184 | ||
185 | + @staticmethod | ||
186 | + @bp.route("/test", methods=["GET"]) | ||
187 | + def test(): | ||
188 | + result = 'c78ca1de8139e62c99d4c4d2050ddd16' | ||
189 | + result = AESHelper.encode('dataman2') | ||
190 | + # result=DES.decode('U2FsdGVkX199Ncuh7+0/HVmonwM9Uz7SYnmF73wtW7c=') | ||
191 | + result2 = AESHelper.decode(result) | ||
192 | + return result2 |
@@ -7,6 +7,7 @@ from .models import * | @@ -7,6 +7,7 @@ from .models import * | ||
7 | from app.util.component.ApiTemplate import ApiTemplate | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | import time | 8 | import time |
9 | from app.models import SM3 | 9 | from app.models import SM3 |
10 | +from app.models import AESHelper | ||
10 | 11 | ||
11 | 12 | ||
12 | class Api(ApiTemplate): | 13 | class Api(ApiTemplate): |
@@ -27,13 +28,13 @@ class Api(ApiTemplate): | @@ -27,13 +28,13 @@ class Api(ApiTemplate): | ||
27 | res["result"] = False | 28 | res["result"] = False |
28 | try: | 29 | try: |
29 | # 业务逻辑 | 30 | # 业务逻辑 |
30 | - username = self.para.get("username") | ||
31 | - password = SM3.encode(self.para.get("pwd")) | ||
32 | - role = self.para.get("role") | ||
33 | - company = self.para.get("company", None) | ||
34 | - position = self.para.get("position", None) | ||
35 | - email = self.para.get("email", None) | ||
36 | - phone = self.para.get("phone", None) | 31 | + username = AESHelper.decode( self.para.get("username", '')) |
32 | + password = SM3.encode(AESHelper.decode(self.para.get("pwd", ''))) | ||
33 | + role = AESHelper.decode(self.para.get("role", '')) | ||
34 | + company = AESHelper.decode(self.para.get("company", '')) | ||
35 | + position = AESHelper.decode(self.para.get("position", '')) | ||
36 | + email = AESHelper.decode(self.para.get("email", '')) | ||
37 | + phone = AESHelper.decode(self.para.get("phone", '')) | ||
37 | # 是否重名 | 38 | # 是否重名 |
38 | if(User.query.filter_by(username=username).one_or_none()): | 39 | if(User.query.filter_by(username=username).one_or_none()): |
39 | res["msg"] = "username 已存在" | 40 | res["msg"] = "username 已存在" |
@@ -23,19 +23,29 @@ Swagger(app, config=swagger_config,template=SWAGGER_TEMPLATE) | @@ -23,19 +23,29 @@ Swagger(app, config=swagger_config,template=SWAGGER_TEMPLATE) | ||
23 | from app.models import SM3 | 23 | from app.models import SM3 |
24 | password = SM3.encode('test') | 24 | password = SM3.encode('test') |
25 | ``` | 25 | ``` |
26 | -## 3 通过http传输的敏感信息要加密 | ||
27 | -1. 使用sm2 | ||
28 | -通过gmssl工具生成sm2的公钥、私钥。[教程](https://github.com/guanzhi/GmSSL) | 26 | +## 3 通过网络传输的敏感信息要加密 |
27 | +~~使用sm2,通过gmssl工具生成sm2的公钥、私钥。~~ | ||
28 | +~~[教程](https://github.com/guanzhi/GmSSL)~~ | ||
29 | 29 | ||
30 | -privatekey使用的pem是`zhou@123` | 30 | +~~1.生成sm2公钥、私钥~~ |
31 | +~~privatekey使用的pem是`zhou@123`~~ | ||
32 | + | ||
33 | +~~2. 使用公钥加密,私钥解密~~ | ||
34 | +~~前端使用sm-crypto,用户与python-gmssl互通~~ | ||
35 | +~~[npm_sm-crypto](https://www.npmjs.com/package/sm-crypto)~~ | ||
36 | + | ||
37 | +使用AES加密敏感信息,前端加密,后端解密。偏移量iv、加密密钥key与前端保持一致,保证解密正确。封装在models.py中 | ||
38 | +依赖组件: | ||
39 | +* pycryptodome | ||
40 | +* Crypto | ||
41 | +* binascii | ||
42 | +参考资料 | ||
43 | +[pycryptodome]() | ||
31 | 44 | ||
32 | -```shell | ||
33 | -gmssl sm2 -genkey -out skey.pem | ||
34 | -gmssl sm2 -pubout -in skey.pem -out vkey.pem | ||
35 | -``` | ||
36 | 45 | ||
37 | -2. 使用公钥加密,私钥解密 | ||
38 | ```python | 46 | ```python |
39 | -privatekey="EOpBYj1pH54b8BsAlkON71Q2c2FXEm+VTPNCgxz4+gVZ2C/pF/Bv152Qj3QH7cBRCUlNeO5SkI02DcwTASmVwESzR4F9IbMvUNxkDngINdcwaSWCTaaRTstNd4FIlJ0CqhDl/TPHFuBoRNBgUDfPJFfl7XYHs4VmOcrp02aXv8Q=" | ||
40 | -publickey="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEsENe/8Sft6rK0h59t2a/6Pf4nzvxvJzc1SzalZe1xSDtUqW/10E/e+RjRbvykyjKzu3vAY1lwv9aU2Tnp6+isw==" | 47 | +from app.models import AESHelper |
48 | + | ||
49 | +encryption=AESHelper.encode('message') | ||
50 | +result=AESHelper.decode(encryption) | ||
41 | ``` | 51 | ``` |
请
注册
或
登录
后发表评论