Криптография Python – данные слишком длинные для размера ключа

Я пытаюсь зашифровать свое сообщение с помощью асимметричного шифрования. Я использую алгоритм 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. Если я увеличу размер ключа до 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 снова слишком длинное.

Как мне понять это правильно?


person PythonEnthusiast    schedule 14.03.2019    source источник
comment
Пол уже дал правильный ответ, но я уделю больше внимания тому факту, что вам нужно зашифровать ключ AES, а не зашифрованный текст. Шифрование — это не сжатие; это не уменьшит сообщение (данные, которые вы шифруете). Причина, по которой работает гибридная криптосистема, заключается в том, что вы сначала защищаете данные с помощью случайного ключа AES, который затем, в свою очередь, защищаете с помощью открытого ключа RSA.   -  person Maarten Bodewes    schedule 17.03.2019


Ответы (3)


Природа криптосистемы RSA такова, что вы не можете зашифровать значение, превышающее модуль (и, фактически, оно должно быть короче, чтобы можно было безопасно зашифровать его, поскольку безопасность RSA частично основана на дополнении).

Если вы хотите зашифровать большую полезную нагрузку, вам нужно вместо этого построить систему, в которой вы шифруете свою полезную нагрузку с помощью симметричного шифра (убедитесь, что это аутентифицированное шифрование! cryptography предоставляет конструкцию под названием Fernet, которая может это сделать), а затем зашифровать симметричный ключ. используя ваш открытый ключ RSA. Затем вы можете отправить оба зашифрованных текста получателю. Получатель может расшифровать зашифрованный ключ RSA, используя закрытый ключ, который у него есть, и расшифровать более крупный зашифрованный текст с помощью полученного ключа.

Если вы создаете эту систему с нуля, рассмотрите возможность использования PyNaCl Box, но если вам нужны более популярные криптографические примитивы тогда такая концепция, как ECIES, также может обеспечить такую ​​возможность без использования RSA.

person Paul Kehrer    schedule 15.03.2019

Асимметричная криптография — это медленная криптографическая техника. Для этого вам следует использовать AES или эквивалент, если вы все еще хотите достичь криптографии с открытым ключом. Зашифруйте данные с помощью AES: создайте объект с заголовком в качестве ключа AES и зашифрованными данными AES в качестве полезной нагрузки... Шифруйте только ключ AES с помощью PKC.

person Z.Developer    schedule 15.03.2019

Попробуйте сократить свое сообщение, используя хеш-алг. как ша256. Затем попробуйте зашифровать сообщение

person tolgaerdonmez    schedule 14.03.2019
comment
Я использую асимметричную криптографию. Если я использую семейство SHA, я не смогу расшифровать его позже. - person PythonEnthusiast; 14.03.2019
comment
Затем вы можете использовать функции RSA, а также шифровать и расшифровывать - person tolgaerdonmez; 31.03.2020