В объяснимой ошибке с шифрованием RSA (с помощью RSAEncryptionPadding.OaepSHA256) на основе входных байтов

#c# #.net-core #cryptography #rsa #public-key-encryption

#c# #.net-ядро #криптография #rsa #шифрование с открытым ключом

Вопрос:

Я использую C # с .net core 3.1 в Windows 10.

Опция 1 в следующем коде успешно шифрует плоские байты, но опция 2 выдает ошибку при методе шифрования. Единственное отличие — входные байты.

 private byte[] TestCode()
{
    var cert = new X509Certificate2("<PEM-FILE-WITH-CERTIFICATE>");
    var publicKey = cert.GetRSAPublicKey();

    var plainConnectionInfo1 = new PlainConnectionInfo()
    {
        ConnectionStringWithoutPath = "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
        Path = "222222222222"
    };

    byte[] encryptedBytes = null;
    byte[] plainBytes = null;
    var option = 1;

    if (option == 1)
    {
        //Option 1
        plainBytes = UTF8Encoding.UTF8.GetBytes(plainConnectionInfo1.ConnectionStringWithoutPath);
        encryptedBytes = publicKey.Encrypt(plainBytes, RSAEncryptionPadding.OaepSHA256);
    }
    else
    {
        //Option 2
        var plainConnectionInfo1Json = JsonConvert.SerializeObject(plainConnectionInfo1);
        plainBytes = UTF8Encoding.UTF8.GetBytes(plainConnectionInfo1Json);
        encryptedBytes = publicKey.Encrypt(plainBytes, RSAEncryptionPadding.OaepSHA256);
    }

    return encryptedBytes;
}
  

Единственное различие между вариантами 1 и 2 заключается в том, что в варианте 2 немного больше текста (по сравнению с вариантом 1). Вариант 2 представляет собой строку json, где, поскольку это просто строка в варианте 1. Обе строки были преобразованы в байты в кодировке UTF8 перед шифрованием.

Вариант 2 выдает мне следующую ошибку:

 Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException
  HResult=0x80090027
  Message=The parameter is incorrect.
  Source=System.Security.Cryptography.Cng
  StackTrace:
   at System.Security.Cryptography.RSACng.EncryptOrDecrypt(SafeNCryptKeyHandle key, ReadOnlySpan`1 input, AsymmetricPaddingMode paddingMode, Void* paddingInfo, Boolean encrypt)
   at System.Security.Cryptography.RSACng.EncryptOrDecrypt(Byte[] data, RSAEncryptionPadding padding, Boolean encrypt)
   at System.Security.Cryptography.RSACng.Encrypt(Byte[] data, RSAEncryptionPadding padding)
  

Основываясь на ошибке, я не смог понять, что я делаю неправильно. Может кто-нибудь, пожалуйста, объяснить?

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

1. Почему вы говорите, что это необъяснимо? В документации указано, что когда RSA.Encrypt выдается a CryptographicException , это означает либо: «заполнение неизвестно, либо не поддерживается этой реализацией». -или — «Длина данных слишком велика для комбинации KeySize и выбранного заполнения». -или — «Операция шифрования завершилась неудачно». Таким образом, это сразу сужает его до трех возможностей. Скорее всего, это длина.

2. Я просматривал только сообщение об исключении. Спасибо, что указали направление на это. Посмотрим, смогу ли я понять, в чем проблема.

3. В этом сообщении объясняется, в чем проблема: crypto.stackexchange.com/questions/42097 /…

Ответ №1:

Я использовал открытый ключ RSA с размером ключа 2048. При таком размере ключа можно было зашифровать только 190 байт в любое время. Это полностью объясняется здесь: https://crypto.stackexchange.com/questions/42097/what-is-the-maximum-size-of-the-plaintext-message-for-rsa-oaep