如何使用RSAPublicKey字段腌制namedtuple子类

时间:2019-03-25 10:57:45

标签: python python-3.x pickle namedtuple python-cryptography

我正在尝试序列化名为tuple的子类的对象,并保留对RSAPublicKey对象的引用。

  • 我将namedtuple子类化以创建不可变的对象实例。

  • 此类的一个字段包含对类型为RSAPublicKey的对象的引用。

  • 我定义__setstate __(self)来序列化RSAPublicKey对象以进行酸洗。

类实现

from collections import namedtuple

class MyClass(namedtuple('MyTuple', ['pub_key', 'foo'])):
    def __getstate__(self):
        return {
            'pub_key': serialize(self.pub_key),
            'foo': self.foo
        }

    def __repr__(self):
        return f'MyClass({serialize(self.pub_key)}, {self.foo})'

正在使用

import pickle

pr, pu = generate_keys()
my_obj = MyClass(pu, 4)

密钥生成和序列化

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend

def generate_keys():
    priv = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    return priv, priv.public_key()

def serialize(key):
    return key.public_bytes(
        serialization.Encoding.PEM,
        serialization.PublicFormat.SubjectPublicKeyInfo
    )

我收到以下错误消息。

TypeError                                 Traceback (most recent call last)
<ipython-input-14-cb7f2cfd2a4d> in <module>
      1 with open('save.dat', 'wb') as f:
----> 2     pickle.dump(my_obj, f)

TypeError: can't pickle CompiledFFI objects

当我将类更改为子类对象时,序列化工作正常。

class MyClass():
    def __init__(self, pub_key, foo):
        self.pub_key = pub_key
        self.foo = foo

    def __getstate__(self):
        return {
            'pub_key': serialize(self.pub_key),
            'foo': self.foo
        }

    def __repr__(self):
        return f'MyClass({serialize(self.pub_key)}, {self.foo})'

1 个答案:

答案 0 :(得分:0)

这将起作用:

from collections import namedtuple

class MyClass(namedtuple('MyTuple', ['pub_key', 'foo'])):
    def __getstate__(self):
        return {
            'pub_key': serialize(self.pub_key),
            'foo': self.foo
        }

    def __repr__(self):
        return f'MyClass({serialize(self.pub_key)}, {self.foo})'




#key generation and serialization

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend

def generate_keys():
    priv = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    return priv, priv.public_key()

def serialize(key):
    return key.public_bytes(
        serialization.Encoding.PEM,
        serialization.PublicFormat.SubjectPublicKeyInfo
    )
import pickle
#dumping
pr, pu = generate_keys()
my_obj = MyClass(pu, 4)

with open('save.dat', 'wb') as f:
    #getting the data from the class
    pickle.dump(my_obj.__getstate__(), f)

是相同的,但是我使用getstate获取数据而不是整个类