正在显示
5 个修改的文件
包含
78 行增加
和
42 行删除
... | ... | @@ -5,31 +5,48 @@ from flask_sqlalchemy import SQLAlchemy |
5 | 5 | import glob |
6 | 6 | import traceback |
7 | 7 | from pyDes import des, PAD_PKCS5, ECB |
8 | - | |
8 | +import json | |
9 | 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 | 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 | 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 | 52 | class DES(): | ... | ... |
1 | 1 | from enum import auto |
2 | 2 | from logging import error |
3 | +from unittest import result | |
3 | 4 | from flasgger import swag_from |
4 | 5 | from app.util import BlueprintApi |
5 | 6 | from app.util import BlueprintApi |
6 | 7 | from flask import Blueprint, render_template, redirect, request, session, jsonify |
7 | 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 | 10 | from authlib.oauth2 import OAuth2Error |
10 | 11 | from authlib.integrations.flask_oauth2 import current_token |
11 | 12 | from . import user_create, client_create, client_query, user_query, user_update, user_delete |
12 | 13 | import configure |
13 | 14 | from app.decorators.auth_decorator import auth_decorator |
14 | 15 | import time |
15 | -from app.models import SM3 | |
16 | +from app.models import SM3, AESHelper | |
17 | + | |
16 | 18 | |
17 | 19 | def current_user(): |
18 | 20 | if "id" in session: |
... | ... | @@ -71,8 +73,6 @@ class DataManager(BlueprintApi): |
71 | 73 | return jsonify(dict(error.get_body())) |
72 | 74 | return render_template("auth/authorize.html", user=user, grant=grant, error=error) |
73 | 75 | |
74 | - | |
75 | - | |
76 | 76 | @staticmethod |
77 | 77 | @bp.route("/token", methods=["POST"]) |
78 | 78 | def issue_token(): |
... | ... | @@ -105,8 +105,7 @@ class DataManager(BlueprintApi): |
105 | 105 | except OAuth2Error as error: |
106 | 106 | return jsonify(dict(error.get_body())) |
107 | 107 | return redirect(url) |
108 | - | |
109 | - | |
108 | + | |
110 | 109 | """接口""" |
111 | 110 | @staticmethod |
112 | 111 | @bp.route("/users", methods=["GET"]) |
... | ... | @@ -165,7 +164,7 @@ class DataManager(BlueprintApi): |
165 | 164 | 获取client列表 |
166 | 165 | """ |
167 | 166 | return client_query.Api().result |
168 | - | |
167 | + | |
169 | 168 | @staticmethod |
170 | 169 | @bp.route("/init", methods=["GET"]) |
171 | 170 | def init(): |
... | ... | @@ -183,3 +182,11 @@ class DataManager(BlueprintApi): |
183 | 182 | else: |
184 | 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 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | import time |
9 | 9 | from app.models import SM3 |
10 | +from app.models import AESHelper | |
10 | 11 | |
11 | 12 | |
12 | 13 | class Api(ApiTemplate): |
... | ... | @@ -27,13 +28,13 @@ class Api(ApiTemplate): |
27 | 28 | res["result"] = False |
28 | 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 | 39 | if(User.query.filter_by(username=username).one_or_none()): |
39 | 40 | res["msg"] = "username 已存在" | ... | ... |
... | ... | @@ -23,19 +23,29 @@ Swagger(app, config=swagger_config,template=SWAGGER_TEMPLATE) |
23 | 23 | from app.models import SM3 |
24 | 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 | 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 | ``` |
\ No newline at end of file | ... | ... |
请
注册
或
登录
后发表评论