Python密码术-数据太长而无法获得密钥大小

时间:2019-03-14 05:40:45

标签: python cryptography key encryption-asymmetric

我正在尝试使用非对称加密对邮件进行加密。我正在使用SHA256算法。密钥大小为2048。这是我的代码:-

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization, hashes

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)

public_key = private_key.public_key()

# saving public key
pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)

with open('public_key.pem', 'wb') as f:
    f.write(pem)


# reading public key
with open("public_key.pem", "rb") as key_file:
        public_key = serialization.load_pem_public_key(
            key_file.read(),
            backend=default_backend()
        )


message = {
    '504201': '504346',
    '504293': '504306',
    '504299': '504273',
    'B.O': 'B.O',
    'Non-Delivery': 'Delivery',
    'regionname': 'Hyderabad',
    'Sirpur (t)': 'Asifabad',
    'ANDHRA PRADESH\nAnnaram B.O': 'ANDHRA PRADESH\nChichdhari Khanapur B.O',
    'officeType': 'S.O',
    'Nirmal': 'Adilabad',
    'circlename': 'Andhra Pradesh',
    'Districtname': 'Adilabad',
    'ANDHRA PRADESH\nBansapalli B.O': 'ANDHRA PRADESH\nDeepaiguda B.O',
    'pincode': '504103',
    'ANDHRA PRADESH\nAndugulpet B.O': 'ANDHRA PRADESH\nBurguda B.O',
    '504202': '504313',
    '504231': '504293',
    'Hyderabad': 'Hyderabad',
    'Khanapur': 'Utnoor',
    'Luxettipet': 'Asifabad',
    'officename': 'dilabad)',
    'ANDHRA PRADESH\nBellalbadi B.O': 'ANDHRA PRADESH\nDhaboli B.O',
    'Taluk': 'Mudhole',
    'ANDHRA PRADESH\nBambara B.O': 'ANDHRA PRADESH\nCoal Chemical Complex S.O',
    'ANDHRA PRADESH\nBangalpet B.O': 'ANDHRA PRADESH\nDantanpalli B.O',
    'salt': 1,
    'divisionname': 'Adilabad',
    'statename\nAda B.O': 'ANDHRA PRADESH\nBirvelli B.O',
    'Delivery': 'Delivery',
    'ANDHRA PRADESH\nBhainsa S.O (A': 'ANDHRA PRADESH\nDhann',
    '504106': '504311',
    'Andhra Pradesh': 'Andhra Pradesh',
    'ANDHRA PRADESH\nArli (T) B.O': 'ANDHRA PRADESH\nChintaguda B.O',
    '504295': '504302',
    'Asifabad': 'Mancherial',
    'ANDHRA PRADESH\nBejjur B.O': 'ANDHRA PRADESH\nDehgaon B.O',
    '504306': '504309',
    '504312': '504296',
    'Adilabad': 'Adilabad',
    'Deliverystatus': 'Delivery',
    'Chennur': 'Utnoor'
}

message = json.dumps(message).encode('utf-8')


encrypted = self.public_key.encrypt(
                message,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )

上面的代码引发异常ValueError: Data too long for key size. Encrypt less data or use a larger key size.,如果我将key_size增加到4096,它将起作用。但是,如果我的数据具有更多密钥,那么即使4096也失败。

作为一种解决方法,我读了多个类似的SO问题,建议使用对称加密来缩短(加密)数据,然后使用非对称方法。

我尝试了以下相同方法:-

from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt(MY_ABOVE_JSON_DUMPS_MESSAGE)
encrypted = self.public_key.encrypt(
                cipher_text,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )

这也会导致相同的错误,因为cipher_text再次过长。

如何正确处理?

3 个答案:

答案 0 :(得分:2)

RSA密码系统的本质是,您不能加密比模数更长的值(实际上,它必须更短才能安全地加密它,因为RSA的安全性部分取决于填充)。

如果您想加密更大的有效负载,则需要构造一个系统,以便使用对称密码对有效负载进行加密(确保它是经过身份验证的加密!cryptography提供了一种名为Fernet的构造,可以做到这一点) ,然后使用RSA公钥加密对称密钥。然后,您可以将两个密文都发送给收件人。收件人可以使用其持有的私钥解密RSA加密密钥,并使用生成的密钥解密较大的密文。

如果您是从头开始构建此系统,请考虑使用PyNaClBox,但是如果您需要更流行的加密原语,那么类似ECIES的概念也可以实现这种能力无需使用RSA。

答案 1 :(得分:0)

非对称密码术是一种缓慢的加密技术,如果您仍想实现公钥密码术,则应使用AES或等效技术。使用AES加密数据:创建一个标头为AES密钥,AES加密数据为有效载荷的对象...仅使用PKC加密AES密钥。

答案 2 :(得分:-1)

尝试使用哈希算法来缩短您的消息。像sha256。然后尝试加密邮件