Как зашифровать большие данные в C с помощью шифрования RSA

#encryption #openssl #rsa

#шифрование #openssl #rsa

Вопрос:

Я использовал следующий код для шифрования строки на C , OpenSSL и он работает нормально, только если текст размером до 256 байтов, он не работает для большего размера:

 void encrypt(char* message, int sourceSzie, char* encryptedMessage, int amp;destSize)
{
    char err[130];
    RSA *rsa_pubkey = NULL;
    FILE *rsa_pub_file = fopen("pubkey_file.bin", "rb");

    if(PEM_read_RSAPublicKey(rsa_pub_file, amp;rsa_pubkey, NULL, NULL) == NULL)
    {
        printf("Error reading public key n");
    }

    if((destSize = RSA_public_encrypt(sourceSzie, (unsigned char*)message,  (unsigned char*)encryptedMessage, rsa_pubkey,     RSA_PKCS1_OAEP_PADDING)) == -1)
    {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %sn", err);
    }
    fclose(rsa_pub_file);
}

char msg[1024];
stcpy(msg, "A test message");
int size;
char encrypted[1024];
encrypt(msg, strlen(msg), encrypted, size);
  

Но если размер строки превышает 256, он не работает и генерирует Data too large error .
Что я должен сделать, чтобы заставить его работать для строки любого размера?

Комментарии:

1. вы можете прочитать 256 байт и зашифровать, а затем продолжить

2. вы имеете в виду, что я вызываю эту функцию для каждых 256 байт и объединяю зашифрованное содержимое?

3. да, вы можете попробовать. 🙂

4. Предлагаемая ссылка не предоставляет решения. Он рекомендует использовать другой libray Nacl вместо OpenSSL. Я должен сделать это с помощью OpenSSL.

5. Хотя с помощью OpenSSL можно создать безопасный протокол шифрования, крайне маловероятно , что он будет создан без большого криптографического фона. OpenSSL — просто плохой инструмент для этой работы.

Ответ №1:

Но если размер строки превышает 256, он не работает и генерирует ошибку Data too large.

Правильно. Шифрование RSA определяется как c = m ^ e mod n . Размер сообщения не может быть больше размера модуля n . Вы можете получить размер модуля с RSA_size() помощью .

Точнее, ограничение modulus size - padding size связано с тем, что сообщения дополняются. Размер заполнения OAEP составляет приблизительно 41 байт, поэтому предел где-то рядом RSA_size(rsa) - 41 .

Я опустил заполнение PKCS, потому что оно небезопасно. В источниках это так #define RSA_PKCS1_PADDING_SIZE 11 . Посмотрите на Пару неудачных лет для индустрии криптографических токенов для доступного обсуждения.

Что я должен сделать, чтобы заставить его работать для строки любого размера?

Вам понадобится сколь угодно большой ключ 😉 Но OpenSSL ограничивает размер вашего ключа до 16 бит. Таким образом, вы не можете сделать ключи произвольно большими.

Кроме того, сложно генерировать эти большие ключи. Время генерации увеличивается с размером ключа, и вы можете потратить пару дней на создание больших ключей.

В вашем конкретном случае:

 char msg[1024];
...
encrypt(rsa, msg, sizeof(msg), ...);
  

Попробуйте сгенерировать ключ, который равен (1024 64) * 8 или 8704 битам. Это должно обрабатывать 1024-байтовый буфер с заполнением.


Чтобы использовать шифрование с открытым ключом в этом случае, вы должны зашифровать строку симметричным шифром, таким как AES. Затем зашифруйте ключ AES с помощью открытого ключа RSA. В основном так работают SSL / TLS и другие.

Если вы используете гибридное шифрование, вам следует выбрать режим, подобный EAX или GCM ; и не CBC режим. EAX и GCM являются аутентифицированными режимами шифрования, и они обеспечивают как конфиденциальность, так и подлинность. С помощью шифрования с проверкой подлинности вы обеспечите конфиденциальность и сможете обнаружить вмешательство.

Если вы решили использовать OpenSSL с AES / GCM, то смотрите примеры его использования в OpenSSL wiki на EVP Authenticated Encryption and Decryption.

Существует несколько криптосистем, которые предоставляют услугу в виде пакета. См. раздел Интегрированная схема шифрования с эллиптической кривой Шоупа (ECIES); или Абдалла, Белларе и Рогауэй в Diffie-Hellman аутентифицирует схемы шифрования (DHAES). К сожалению, OpenSSL не предоставляет ни того, ни другого.

Но если вас интересуют ECIES или DHAES, тогда взгляните на Crpyto . Библиотека предлагает оба варианта. Пример его использования в Crypto см. В разделе Схема интегрированного шифрования с эллиптической кривой.

Комментарии:

1. Спасибо за подробности. Итак, если я продолжу использовать OpenSSL с ключом 256 и использую AES вместо RSA, проблема будет решена?

Ответ №2:

Я нашел решение по ссылке https://shanetully.com/2012/06/openssl-rsa-aes-and-c /.

Функции Crypto::aesEncrypt() и Crypto::aesDecrypt() способны шифровать / расшифровывать строки любого размера.