0

我试图理解公钥加密,所以我使用 PyCryptodome 和 Python 3 上的 RSA/PKCS1_OAEP 模块编写了这个小模块来帮助我。但是,我不断收到错误消息:

NameError:未定义名称“aesenc”

这是一个两部分的问题:

  1. 在独立代码(在类之外)中,arg = default_val 代码将起作用,但我很确定这段代码会引发错误(假设我修复了问题 #2)。我也知道我不能使用 self.default_val 因为它需要先创建一个对象。如何分配默认值(在这种情况下,对象的私钥/公钥?)

  2. 关于错误消息,vgrep 显示套件在调用之前已声明,但我仍然收到 NameError。有人可以看看,让我知道我做错了什么吗?

模块:(分解成部分,因为 SO 不断混淆代码)

from passlib.context import CryptContext
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Random import get_random_bytes

班上:

class statEnc:
    pubcipher = None
    privcipher = None
    pubkeystr = None
    privkeystr = None
    sessionkey = None

    def __init__(self, pubkeystr = None, privkeystr = None, sessionkey = None):
        self.pubkeystr = pubkeystr
        self.privkeystr = privkeystr
        self.sessionkey = sessionkey
        if pubkeystr == None or privkeystr == None:  #if blank, generate keys
            self.random_generator = Random.new().read
            self.keys = RSA.generate(1024, self.random_generator)
            self.pubkey = self.keys.publickey()
            self.pubkeystr = self.pubkey.exportKey(format='PEM',
                                            passphrase=None,
                                            pkcs=1)
            self.pubcipher = PKCS1_OAEP.new(self.pubkey)
            self.privcipher = PKCS1_OAEP.new(self.keys)
            self.privkeystr = self.keys.exportKey(format='PEM',
                                                passphrase=None,
                                                pkcs=1)
            self.privkey = self.keys.exportKey()
        else:  #import the keys
            self.pubkey = RSA.importKey(pubkeystr)
            self.pubcipher = PKCS1_OAEP.new(pubkey)
            self.privkey = RSA.importKey(privkeystr)
            self.pubcipher = PKCS1_OAEP.new(privkey)
            if sessionkey == None:
                sessionkey = get_random_bytes(16)
            else:
                self.sessionkey = sessionkey

    def encrypt_val(self, session_key, cipher = pubcipher):
        # a little ditty to hep encrypt the AES session key
        try:
            session_key = session_key.encode('utf8')
        except:
            pass
        ciphertext = cipher.encrypt(session_key)
        return ciphertext


    def decrypt_val(self, ciphertext, cipher = privcipher):
        # a little ditty to hep decrypt the AES session key
        session_key = cipher.decrypt(ciphertext)
        try:
            session_key = session_key.decode('utf8')
        except:
            pass
        return session_key

    def aesenc(self, data, *args):
        #encrypt the payload using AES
        key = ''
        if args:
            if 'str' in str(type(args[0])):
                try:
                    key = int(args[0])
                except:
                    key = get_random_bytes(16)
        else:
            key = get_random_bytes(16)
        try:
            data = data.encode('utf8')
        except:
            pass
        cipher = AES.new(key, AES.MODE_EAX)
        ciphertext, tag = cipher.encrypt_and_digest(data)
        aesencdict = {
        'ciphertext' : ciphertext,
        'tag' : tag,
        'nonce' : cipher.nonce ,
        'key' : key
        }
        return(aesencdict)

    def aesdec(self, aesdict):
        #decrypt the AES encrypted payload
        cipher = AES.new(aesdict['key'], AES.MODE_EAX, aesdict['nonce'])
        data = cipher.decrypt_and_verify(aesdict['ciphertext'], aesdict['tag'])
        try:
            data = data.decode('utf8')
        except:
            pass
        return data

    def end2enc(self, val, cipher = pubcipher):
        # a master function to first encrypt the payload
        val = str(val)
        encval = aesenc(val)
        # and then PK encrypt the key
        encval['key'] = encrypt_val(encval['key'], cipher)
        return encval

    def end2dec(self, encval, cipher = privcipher):
        encval['key'] = decrypt_val(encval['key'], cipher)
        outval = aesdec(encval['aesdict'], encval['key'])
        return outval

测试功能及主要:

def test():
    val = { 'test' : "hello"}
    keypair = statEnc()
    print(str(type(keypair)))
    encval = keypair.end2enc(val, keypair.pubcipher)
    outval = keypair.end2dec(encval, keypair.privcipher)
    print(val, outval)
    if val == eval(outval):
        return(val)
    else:
        return False

if __name__ == '__main__':
    test()

[更新] Traceback 如下:

[guha@katana stat]$ python statenc.py 
<class '__main__.statEnc'>
Traceback (most recent call last):
  File "statenc.py", line 124, in <module>
    test()
  File "statenc.py", line 115, in test
    encval = keypair.end2enc(val, keypair.pubcipher)
  File "statenc.py", line 100, in end2enc
    encval = aesenc(val)
NameError: name 'aesenc' is not defined
4

1 回答 1

0

睡在我的问题上,醒来时头脑清醒,瞧!答案就出来了。

第二个问题的答案如下: 2. 放一个简单的'self'。解决了这个问题 - 我调用的是 'aesenc(params)' 而不是 'self.aesenc(params)'。我真傻,真的。

在这个 SO question中回答了问题 1 。

于 2017-07-05T04:58:58.640 回答