当你需要在不同进程或设备间安全无损的传递Python对象时,可以尝试使用Knight-bus库。
想象一下你可以把函数直接发射到服务器上的某个进程里供它调用,或是把一个自定义的类对象(比如:树)传输到服务器上而无需考虑以json传递对数据结构的影响.传输时也无需担心线路是否安全,对象大小是否超过了buffer size.
可传输的对象种类
Knight-bus使用pickle
来序列化对象,所以可传输的对象种类与之是一致的:
None
, 布尔变量True
和False
- 整数(
int
),长整数(long int
),浮点数(float
) - 普通的或Unicode编码的字符串(
str
) - 仅包含可可序列化对象的元组(
tuple
),列表(list
),集合(set
)和字典(dic
) - 在模块顶层定义的函数(
function
),以及内置函数(built-in function
) - 在模块顶层定义的类(
class
) - 当类的
__dict__
成员或__getstate__()
返回值是可序列化时,实例化出的类对象
如何使用Knight-bus
首先需要安装:pip install knight-bus
非加密传输
在网络环境绝对安全时(比如在同一计算机的不同进程间传递时),可以考虑使用Knight-bus的非加密传输来传输对象.
- 启动接收器
Receiver
from knight_bus.Receiver import Receiver receiver = Receiver(encrypt_method="none") obj = receiver.recv() # 这一步是阻塞的,直到接收到对象后才会返回
- 使用发送器
Sender
发送对象from knight_bus.Sender import Sender sender = Sender(encrypt_method="none", ip="....") #ip默认是127.0.0.1,所以如果是本机传输,可以不指定ip sender.send([1,2,"3",{"4":"four"}])
然后对象就会发送到接收端(实际上接收端会产生一个原来对象的深拷贝)
加密传输
加密传输在网络环境不能保证安全时至关重要,Knight-bus的RSA非对称加密传输机制能提供一条安全无损的传输路径.
- 获取一对RSA密钥
from loopyCryptor import generate_RSA_key pub_key, pri_key = generate_RSA_key() # 然后你可以把密钥保存到文件里或者print出来直接拷贝到源代码里 ...
- 启动接收器
Receiver
from knight_bus.Receiver import Receiver # 你在上一步生成的私钥 key = b"-----BEGIN RSA PRIVATE KEY-----\n ......" receiver = Receiver(key=key) obj = receiver.recv() # 这一步是阻塞的,直到接收到对象后才会返回
- 使用发送器
Sender
发送对象from knight_bus.Sender import Sender key = b"-----BEGIN PUBLIC KEY-----\n ......" sender = Sender(key=key, ip="....") sender.send([1,2,"3",{"4":"four"}])
然后对象就会发送到接收端(实际上接收端会产生一个原来对象的深拷贝)
传输机制
knight-bus
基于pickle
,pycryptodome
,socket
和loopyCryptor
以下是knight-bus(默认)的RSA加密传输流程.你也可以调整一些参数来自定义工作流程。
Reciever
实例化后,它将创建一个socket,绑定8900端口并等待连接。Sender
实例化后,它将创建一个到Reciever
的socket。稍后在Sender.send
被调用时,它将计算传输对象的md5和大小,并使用给定的RSA公钥对结果以及salt和magic code进行加密,最后将密文发送到Reciever
。- 当
Reciever
获得密文时,它使用RSA私钥解密文本并检查magic code。如果匹配,它将计算包含salt,对象大小和md5的列表的md5。然后将结果与magic code签名,并将签名发回。 - 然后
Sender
验证签名,若通过则开始传输加密对象。 Reciever
获取加密对象并检查其md5和大小(确保它是无损坏的),如果匹配,则将其解密为原对象。- 最后,用户将获得原始对象的深拷贝。