在Python中使用gmssl包实现SM2加密和解密

1.安装gmssl包

python 复制代码
 pip install gmssl

安装完成后,您可以使用 gmssl 提供的函数来修改 User 类中的 set_password 和 verify_password 方法,以便使用 SM2 加密和解密密码。以下是使用 gmssl 的 User 类示例:

python 复制代码
import datetime
from tortoise.models import Model
from tortoise import fields
import gmssl

# User 类定义
class User(Model):
    user_id = fields.IntField(pk=True)
    user_no = fields.CharField(max_length=20, unique=True)
    username = fields.CharField(max_length=100, unique=True)
    # 密码字段,实际存储加密后的密码
    passwd = fields.BinaryField()
    email = fields.CharField(max_length=100, unique=True)
    phone = fields.CharField(max_length=20, unique=True)
    created_time = fields.DatetimeField(auto_now_add=True)
    modified_time = fields.DatetimeField(auto_now=True)
    end_time = fields.DatetimeField()
    isactive = fields.BooleanField(default=True)

    # 使用 SM2 加密密码
    def set_password(self, password: str, public_key):
        encrypted_password = public_key.encrypt(password.encode())
        self.passwd = encrypted_password

    # 验证密码
    def verify_password(self, password: str, private_key):
        decrypted_password = private_key.decrypt(self.passwd).decode()
        return decrypted_password == password

# 创建 User 表
async def init_user_table():
    await User.create_table()

# 使用示例
async def main():
    # 生成 SM2 密钥对
    sm2_crypt = gmssl.sm2.CryptSM2(
        public_key=None,
        private_key=None
    )
    private_key, public_key = sm2_crypt.generate_keypair()

    # 创建用户
    user = User(
        user_no='U001',
        username='john_doe',
        email='john@example.com',
        phone='1234567890',
        end_time=datetime.datetime.now() + datetime.timedelta(days=365),
    )
    user.set_password('securepassword', public_key)
    await user.save()

    # 查询用户
    users = await User.filter(username='john_doe')
    for u in users:
        print(u.username)
        # 验证密码
        is_valid = u.verify_password('securepassword', private_key)
        print(f'Password is valid: {is_valid}')

# asyncio.run(main())

在实际应用中,私钥(private_key)和公钥(public_key)通常是一次生成并存储起来多次使用的,而不是每次使用时临时生成。私钥必须保密并安全存储,因为它用于解密数据和解密数字签名。公钥则可以公开分发,因为它用于加密数据和验证数字签名。

对于密码加密,通常的做法是:

在用户注册时,生成一对新的 SM2 密钥。

将私钥安全地存储在服务器上,最好使用密码学安全的随机数生成器来生成私钥。

将公钥存储在数据库中,与用户的其它信息一起。

使用公钥来加密用户的密码,并将加密后的密码存储在数据库中。

在用户登录时,使用存储的私钥来解密加密的密码,以便与用户输入的密码进行比较。

这种方法的优点是,即使加密后的密码被泄露,没有私钥,攻击者也无法解密密码。此外,由于每次加密使用的是同一个公钥,所以可以在不改变密码的情况下更新私钥,只需在更新时同时解密和重新加密所有密码即可。

在代码中,您需要确保私钥的安全性,不要在客户端或公共代码中暴露私钥。通常,私钥会在服务器的配置文件中或使用环境变量进行管理,并且只有授权的服务器端代码才能访问它。公钥可以安全地公开,因为它不用于解密操作。

相关推荐
Python×CATIA工业智造2 小时前
Frida RPC高级应用:动态模拟执行Android so文件实战指南
开发语言·python·pycharm
onceco2 小时前
领域LLM九讲——第5讲 为什么选择OpenManus而不是QwenAgent(附LLM免费api邀请码)
人工智能·python·深度学习·语言模型·自然语言处理·自动化
狐凄3 小时前
Python实例题:基于 Python 的简单聊天机器人
开发语言·python
悦悦子a啊4 小时前
Python之--基本知识
开发语言·前端·python
笑稀了的野生俊6 小时前
在服务器中下载 HuggingFace 模型:终极指南
linux·服务器·python·bash·gpu算力
Naiva6 小时前
【小技巧】Python+PyCharm IDE 配置解释器出错,环境配置不完整或不兼容。(小智AI、MCP、聚合数据、实时新闻查询、NBA赛事查询)
ide·python·pycharm
路来了6 小时前
Python小工具之PDF合并
开发语言·windows·python
蓝婷儿6 小时前
Python 机器学习核心入门与实战进阶 Day 3 - 决策树 & 随机森林模型实战
人工智能·python·机器学习
AntBlack7 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
.30-06Springfield7 小时前
决策树(Decision tree)算法详解(ID3、C4.5、CART)
人工智能·python·算法·决策树·机器学习