如何使用RSAPublicKey字段pickle namedtuple子类

问题描述 投票:1回答:1

我正在尝试序列化子类namedtuple并保持对RSAPublicKey对象的引用的对象。

  • 我将一个namedtuple子类化为创建不可变对象实例。
  • 我的类中的一个字段包含对RSAPublicKey类型的对象的引用。
  • 我定义了__setstate __(self)来序列化RSAPublicKey对象以进行pickle。

类实现

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})'
python python-3.x pickle namedtuple python-cryptography
1个回答
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来获取数据,而不是整个类

© www.soinside.com 2019 - 2024. All rights reserved.