RSACryptoServiceProvider не забезпечує послідовного виводу

Мені потрібно шифрувати деякий текст за допомогою RSA, а потім відновити його пізніше за допомогою приватного ключа. Моя проблема полягає в тому, що RSACryptoServiceProvider.Encrypt() виводить інше значення кожен раз, навіть при використанні однієї ключа. Ось мій код, який я поклав у LINQpad для тестування:

CspParameters cp = new CspParameters();
cp.KeyContainerName = "MyKey";
cp.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

// using LINQpad to verify the key is loaded properly -- same every time
rsa.ToXmlString(true).Dump();

byte[] rgb = new ASCIIEncoding().GetBytes("Hello world");
byte[] xx = rsa.Encrypt(rgb, false);
string b64 = Convert.ToBase64String(xx);

// this changes every time:
b64.Dump();

Я вгадую, що клас повинен використовувати щось інше, а також ключ, щоб вплинути на вихід, але я намагаюсь з'ясувати, що.

3
Коли ви розшифровуєте дані, чи отримуєте ви один і той же результат?
додано Автор robert, джерело
Добре, я думав, що не став. Ось чому я взяв все це назад, щоб дивитися на зашифрований текст, щоб побачити, що воно було однаковим. Але я не зміг вирішити цю проблему, перш ніж я пішов, щоб оновити мою відповідь - я думаю, що я переплутав типи підкладки у другому параметрі шифрування ().
додано Автор gordonmleigh, джерело

2 Відповіді

Різний вихід ідеально нормальний. Це пов'язано з тим, що ваші дані проставляються PKCS # 1 або OAEP - і обидва використовують/додають деякі випадкові дані.

Тепер це не так, як ви повинні використовувати RSA. Багато причин, але найбільш прямий для вас, полягає в тому, що розмір padding/block обмежує кількість байтів, які ви можете шифрувати (а RSA занадто повільно розглядає цикл шифрування блоків).

Я написав запис блогу на цю тему, який описує, як можна змішувати симетричні (краще швидкість, без обмежень розміру) з асиметричним шифруванням - отримання найкращого з обох світів :-)

1
додано

Той факт, що текст шифру відрізняється кожен раз, коли один і той же прозорий текст зашифрований, не означає, що його неможливо розшифрувати послідовно.
Це дійсно є ознакою хорошого криптографічного алгоритму, що дозволяє мати таку поведінку, що робить її більш стійкою до різних атак.

Це відбувається тому, що логіка шифрування вводить випадковість у процесі, наприклад, шляхом систематичного додавання деяких випадкових байтів до самого відкритого тексту. Поки логіка розшифровки знає ігнорувати ці байти після розшифровки всього шифруемого тексту, він може відтворювати оригінальний прозорий текст.

Я пропоную вам взяти будь-який екземпляр цього тексту b64, відправити його в зворотний процес і побачити, що "rgb", що випускається, є "Hello world" у всіх випадках.

1
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug