mirror of https://github.com/veops/cmdb.git
feat: 密码存储 增加内置 AES 加密;增加 Vault Transit 加密
This commit is contained in:
parent
6503d32e6e
commit
1b2a97890a
|
@ -26,6 +26,7 @@ Flask-Bcrypt = "==1.0.1"
|
|||
Flask-Cors = ">=3.0.8"
|
||||
ldap3 = "==2.9.1"
|
||||
pycryptodome = "==3.12.0"
|
||||
hvac = "==1.2.1"
|
||||
# Caching
|
||||
Flask-Caching = ">=1.0.0"
|
||||
# Environment variable parsing
|
||||
|
|
|
@ -6,6 +6,7 @@ import time
|
|||
from typing import Set
|
||||
|
||||
import elasticsearch
|
||||
import hvac
|
||||
import redis
|
||||
import six
|
||||
from Crypto.Cipher import AES
|
||||
|
@ -286,3 +287,35 @@ class AESCrypto(object):
|
|||
text_decrypted = cipher.decrypt(encode_bytes)
|
||||
|
||||
return cls.unpad(text_decrypted).decode('utf8')
|
||||
|
||||
|
||||
class VaultTransitCrypto:
|
||||
TRANSIT_KEY_NAME = 'cmdb-hvac-key'
|
||||
client = None
|
||||
|
||||
@classmethod
|
||||
def init_client(cls):
|
||||
if not cls.client or not cls.client.is_authenticated():
|
||||
cls.client = hvac.Client(
|
||||
url=current_app.config.get('VAULT_URL'),
|
||||
token=current_app.config.get('VAULT_TOKEN'),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def encrypt(cls, text):
|
||||
cls.init_client()
|
||||
cls.client.secrets.transit.create_key(name=cls.TRANSIT_KEY_NAME)
|
||||
encrypt_data_response = cls.client.secrets.transit.encrypt_data(
|
||||
name=cls.TRANSIT_KEY_NAME,
|
||||
plaintext=base64.b64encode(text.encode()).decode(),
|
||||
)
|
||||
return encrypt_data_response['data']['ciphertext']
|
||||
|
||||
@classmethod
|
||||
def decrypt(cls, ciphertext):
|
||||
cls.init_client()
|
||||
decrypt_data_response = cls.client.secrets.transit.decrypt_data(
|
||||
name=cls.TRANSIT_KEY_NAME,
|
||||
ciphertext=ciphertext,
|
||||
)
|
||||
return base64.b64decode(decrypt_data_response['data']['plaintext']).decode()
|
||||
|
|
|
@ -16,6 +16,7 @@ from api.lib.database import Model
|
|||
from api.lib.database import SoftDeleteMixin
|
||||
from api.lib.perm.acl.const import ACL_QUEUE
|
||||
from api.lib.perm.acl.const import OperateType
|
||||
from api.lib.utils import AESCrypto, VaultTransitCrypto
|
||||
|
||||
|
||||
class App(Model):
|
||||
|
@ -126,7 +127,7 @@ class User(CRUDModel, SoftDeleteMixin):
|
|||
catalog = db.Column(db.String(64))
|
||||
email = db.Column(db.String(100), unique=True, nullable=False)
|
||||
mobile = db.Column(db.String(14), unique=True)
|
||||
_password = db.Column("password", db.String(80))
|
||||
_password = db.Column("password", db.String(128))
|
||||
key = db.Column(db.String(32), nullable=False)
|
||||
secret = db.Column(db.String(32), nullable=False)
|
||||
date_joined = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
@ -155,14 +156,21 @@ class User(CRUDModel, SoftDeleteMixin):
|
|||
return self._password
|
||||
|
||||
def _set_password(self, password):
|
||||
self._password = hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
md5_password = hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
if current_app.config.get("ENCRYPT_PASSWORD_TYPE") == 'VAULT':
|
||||
self._password = VaultTransitCrypto.encrypt(md5_password)
|
||||
else:
|
||||
self._password = AESCrypto.encrypt(md5_password)
|
||||
|
||||
password = db.synonym("_password", descriptor=property(_get_password, _set_password))
|
||||
|
||||
def check_password(self, password):
|
||||
def check_password(self, md5_password):
|
||||
if self.password is None:
|
||||
return False
|
||||
return self.password == password or self.password == hashlib.md5(password.encode('utf-8')).hexdigest()
|
||||
if current_app.config.get("ENCRYPT_PASSWORD_TYPE") == 'VAULT':
|
||||
return VaultTransitCrypto.decrypt(self.password) == md5_password
|
||||
else:
|
||||
return AESCrypto.decrypt(self.password) == md5_password
|
||||
|
||||
|
||||
class RoleQuery(BaseQuery):
|
||||
|
|
|
@ -18,6 +18,7 @@ Flask-RESTful==0.3.10
|
|||
Flask-SQLAlchemy==2.5.0
|
||||
future==0.18.3
|
||||
gunicorn==21.0.1
|
||||
hvac==1.2.1
|
||||
itsdangerous==2.1.2
|
||||
Jinja2==3.1.2
|
||||
jinja2schema==0.1.4
|
||||
|
|
|
@ -97,3 +97,7 @@ BOOL_TRUE = ['true', 'TRUE', 'True', True, '1', 1, "Yes", "YES", "yes", 'Y', 'y'
|
|||
|
||||
# # messenger
|
||||
USE_MESSENGER = True
|
||||
|
||||
ENCRYPT_PASSWORD_TYPE = "VAULT" # "VAULT" or "AES"
|
||||
VAULT_URL = 'http://' # 当 ENCRYPT_PASSWORD_TYPE 为 VAULT 时,需要配置
|
||||
VAULT_TOKEN = '' # 当 ENCRYPT_PASSWORD_TYPE 为 VAULT 时,需要配置
|
||||
|
|
Loading…
Reference in New Issue