提交 7e4b2a256e9497066da286041d3f0d5cb511d74c

作者 qianyingz
1 个父辈 7933f315

敏感信息AES加密

@@ -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 ```
@@ -20,4 +20,5 @@ kazoo==2.8.0 @@ -20,4 +20,5 @@ kazoo==2.8.0
20 paramiko==2.8.0 20 paramiko==2.8.0
21 requests==2.26.0 21 requests==2.26.0
22 schedule==1.1.0 22 schedule==1.1.0
23 -gmssl==3.2.1  
  23 +gmssl==3.2.1
  24 +pycryptodome==3.13.0
注册登录 后发表评论