#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()
способны шифровать / расшифровывать строки любого размера.