【SQLAlchemy】基于RSA双向加密存储

用sqlalchemy的时候要实现密码的双向加密不方便调用mysql的ENCODE函数

这里给出一个基于rsa实现双向加密,在sqlalchemy定义model的时候用起来很方便,其他ORM应该也能采用相同的思路(话说我也不知道mysql是基于什么双向加密的)

加密解密函数

import rsa
def encrypt(msg, priv_str):
    if isinstance(msg, str):
        msg = msg.encode()
    if isinstance(priv_str, str):
        priv_str = priv_str.encode()
    privkey = rsa.PrivateKey.load_pkcs1(priv_str)
    return rsa.encrypt(msg, privkey)

def decrypt(msg, priv_str):
    if isinstance(msg, str):
        msg = msg.encode()
    if isinstance(priv_str, str):
        priv_str = priv_str.encode()
    privkey = rsa.PrivateKey.load_pkcs1(priv_str)
    return rsa.decrypt(msg, privkey).decode('utf-8')
复制代码

有几个注意的地方:

  • 参数是私钥字符串,因为直接从rem文件读取比较方便
  • rsa加解密函数返回的都是bytes
  • 解密decode了加密没有,是因为rsa加密后的bytes是没法decode到utf-8的,所以存储类型是Binary。这点在http发送签名的时候会出现坑,那就是另外的故事了

model定义

class User(Base):
    _pw = Column(Binary)

    @property
    def pw(self):
        with open('private.rem', 'r') as f:
            return decrypt(self._pw, f.read())
    @pw.setter
    def pw(self, pw):
        with open('private.rem', 'r') as f:
            self._pw = encrypt(pw, f.read())
    def pw_verify(self, pw):
        return pw == self.pw
# Usage
user = User(pw='password')
user.pw = 'password'
print(user.pw) # 'password'
print(user._pw) # b'eK:\x0f)\xa7}Gx\xe6\xfd\x14\xf3\xd8\xf1\x08f\xac\xdbL\xf23\x07#\...'
复制代码

这里没啥说的,就是用了property装饰器。

有个问题是,如果在初始化对象的时候给pw赋值,能行是能行,IDE不干,非要给你标出来,强迫症就很烦,我都在下一行赋

转载于:https://juejin.im/post/5cd4f2b8f265da03587c18d5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值