使用另一个公钥加密包含公钥的邮件

时间:2017-01-17 08:03:33

标签: python encryption pycrypto

我有两个非对称密钥对client_key,A和another_key,B。 我想用B&#39的公钥发送加密dict。但是,dict必须包含A的公钥,如下例所示:

message_dict = {
  'hostname': socket.getfqdn(),
  'request': 'MY_REQUEST',
  'client_pub_key': client_key.publickey().exportKey(),
}

我做了上述json.dumps并用B&#39的公钥加密。解密后,我没有得到相同的消息。我注意到只有在词典中加入client_pub_key才会出错。

我一直在网上寻找答案,这可能是为什么它可能出错:

  • 邮件太长,无法使用B&#39的公钥加密
  • client_pub_key具有特殊字符,导致JSON编码混乱的情况

我尝试了以下内容:

  • 使用pickle代替JSON
  • 使用binascii.hexlify编码client_pub_key
  • 使用base64.b64encode编码client_pub_key
  • 使用Crypto.Util.RFC1751.key_to_english转换为某些字符client_pub_key
  • 设置B键的2048字节和A键的1024字节

我上面所有的努力都失败了。因此,我在这里寻求帮助。

我的问题:如何加密上述dict格式的邮件,以便将其发送到服务器? (我使用节俭的TTornadoStreamTransportTBinaryProtocol,如果有帮助的话)

我的测试代码段:

#!/usr/bin/env python

import base64
import binascii
import json
import pickle
import socket

from Crypto.PublicKey import RSA
from Crypto.Util.RFC1751 import key_to_english

client_key = RSA.generate(1024)

message_dict = {
  'hostname': socket.getfqdn(),
  'request': 'MY_REQUEST',
  'client_pub_key': int(binascii.hexlify(client_key.publickey().exportKey()),16),
}

another_key = RSA.generate(2048)

print '\n\nDICT: {0}'.format(message_dict)
message = json.dumps(message_dict)

print '\n\nMESSAGE: {0}'.format(message)
encrypted = another_key.publickey().encrypt(message, 32)[0]

print '\n\nENCRYPTED: {0}'.format(encrypted)

decrypted = another_key.decrypt(encrypted)
print '\n\nMESSAGE: {0}'.format(decrypted)

result = json.loads(decrypted)
print '\n\nDICT: {0}'.format(result)
# result should be same message_dict

1 个答案:

答案 0 :(得分:0)

您的问题是,您尝试加密的邮件永远不会超过n模数!

由于:

cipher = message ** e(mod N)

如果您的消息在数字上大于RSA模块(在您的情况下为2048 BITS - 而不是字节),您将无法获得正确的密文,并且解密将永远不会起作用。 (数学)

在你的情况下会发生这种情况。

你应该小心,因为我猜,在json.dumps()之后,消息不应大于(在2048bit another_key的情况下)2048 // 8 = 256字节长 - 你可以在json之后测试它.dumps()通过len(消息)。 在您的上述示例中,您的消息长度将大于700字节...并且700> 256。

只是为了表明这个意思: 首先尝试一个长度为256字节的消息:

>>> import json
>>> from Crypto.PublicKey import RSA
>>> another_key = RSA.generate(2048)
>>> message_dict = {'t':'a'*248}
>>> message = json.dumps(message_dict)
>>> len(str(message))
256
>>> enc = another_key.publickey().encrypt(message, 32)[0]
>>> dec = another_key.decrypt(enc)

你会看到,在这个例子中,消息的长度恰好是256个字节(不是位,但是256 * 8 = 2048位) - 并且它工作正常!

但现在让我们尝试257字节的长度(超过n模的长度(2048位= 256字节):

>>> import json
>>> from Crypto.PublicKey import RSA
>>> another_key = RSA.generate(2048)
>>> message_dict = {'t':'a'*249}
>>> message = json.dumps(message_dict)
>>> len(str(message))
257
>>> enc = another_key.publickey().encrypt(message, 32)[0]
>>> dec = another_key.decrypt(enc)

在这种情况下,dec!= enc - 因为消息在数值上大于n modulo。

如果您将在数学上理解其原因,请查看" cipher = message ** e(mod N)"的含义。 ;)