Почему RSACryptoServiceProvider.Encrypt () вывод не стабилен?

до сегодняшнего дня я жил под впечатлением, что шифрование RSA с использованием RSA является детерминированным. В конце концов, как должна работать проверка подписи, если это не так?

к моему большому удивлению, .Сети RSACryptoServiceProvider не имеет стабильного вывода при шифровании того же набора байтов с теми же ключами:

[Fact]
public void Learning()
{
    const int keySize = 1024;

    System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(keySize);

    var bytes = GenerateRandomDataWithLength( 36 );

    for (int i = 0; i < 4; i++)
        Assert.Equal( rsa.Encrypt( bytes, false ), rsa.Encrypt( bytes, false ) );
}

byte[] GenerateRandomDataWithLength( int length )
{
    Random r = new Random();

    byte[] data = new byte[length];
    r.NextBytes( data );

    return data;
}

Я просмотрел спецификация PKCS и я понимаю математику за RSA, поэтому мне действительно интересно, почему я наблюдаю за выходом нестабильный.

реализация RSA Mono имеет стабильный выход. Нестабильный выход Encrypt не влияет на расшифровку, что вполне возможно и дает ожидаемые данные.

1 ответов


шифрование RSA является чистой математикой, поэтому он даст вам тот же результат каждый раз. Однако зовет Encrypt в .NET не просто делает шифрование RSA.

почему ? заполнение PKCS#1 (по умолчанию при использовании false на Encrypt) сделает каждый зашифрованный результат другим, потому что он включает случайные данные (для заполнения цели).

Mono имеет то же самое поведение (по крайней мере на моей системе, см. Примечание). Однако, если вы используете EncryptValue, которым Моно поддерживает, но .NET не (ограничение CryptoAPI), а затем нет padding будет сделано и зашифрованный результат будет одинаковым каждый раз.

Примечание: если у вас есть разные результаты, пожалуйста, заполните отчет об ошибке наhttp://bugzilla.xamarin.com и включите номер версии, который вы используете.