Python / SqlAlchemy使用M2Crypto计算列

时间:2017-05-10 16:16:57

标签: python postgresql sqlalchemy m2crypto

我在postgres数据库中有两个外来表,它们是“相关的”,没有通过“外键”正式连接(出于安全原因),称为帐户和配置文件。

帐户有一个名为'encrypted_UUID'的列,而Profile有一个名为'UUID'的列,其中Account中的一行可以与Profile中的一行非正式关联,方法是解密帐户的UUID并使用解密的方式搜索Profile中的行UUID。

我已成功使用M2Crypto从帐户解密个别UUID:

import hashlib
import M2Crypto.EVP

ENCRYPT = 1
DECRYPT = 0

def hash_key(key_phrase=None):
    hasher512 = hashlib.sha512()
    if key_phrase is None:  # get from vault
        key_phrase = vault_key
    hasher512.update(str(key_phrase))
    return hasher512.digest()

def crypt(data, key_phrase=None, iv=None, whichway=DECRYPT):
    key = hash_key(key_phrase)
    if iv is None:
        iv = vault_iv
    cipher = M2Crypto.EVP.Cipher(algo, key, iv, whichway)
    return cipher.update(data) + cipher.final()

def decrypt(data, key_phrase=None, iv=None):
    return crypt(data, key_phrase, iv, DECRYPT)

def encrypt(data, key_phrase=None, iv=None):
    #data = data.encode('utf-8')
    return crypt(data, key_phrase, iv, ENCRYPT)

其中vault_keyvault_ivalgo是我将保密但用于加密/解密的内容。

因此,对于任何帐户,我可以说decrypt(Account.query.all()[0].uuid)并获取解密的UUID字符串,然后查找具有该解密的UUID的相应配置文件。

现在,我正在尝试使用SQLAlchemy为两个表帐户和配置文件进行连接,使用两个帐户为帐户上的解密UUID使用计算列。

以下是我对模特的看法:

class Account(db.Model):
    encrypted_uuid = db.Column(db.LargeBinary())
    ...
    @hybrid_property
    def decrypted_uuid(self):
        return decrypt(self.encrypted_uuid)

    @decrypted_uuid.expression
    def decrypted_uuid(cls):
        return decrypt(cls.encrypted_uuid)

class Profile(db.Model):
    uuid = db.Column(db.String())
    ...

这是我对加入的尝试:

query = db.session
            .query(Account.email, Profile.last_name, Profile.first_name)
            .join(Profile, Profile.uuid == Account.decrypted_uuid)

但是,当我尝试进行查询时出现错误:

TypeError: expected a readable buffer object

可以将堆栈追溯到decrypt模型中cls.encrypted_uuid上的Account调用。

根据我过去的经验,通过几乎完全模仿hybrid_property / method定义下的计算来获得计算列。

我有一种感觉这是因为我试图在类decrypt而不是像sqlalchemy.orm.attributes.InstrumentedAttribute object函数期望的str类上调用decrypt

0 个答案:

没有答案