Я пытаюсь зашифровать и расшифровать данные с помощью RSA на С#. У меня есть следующий модульный тест MSTest:
const string rawPassword = "mypass";
// Encrypt
string publicKey, privateKey;
string encryptedPassword = RSAUtils.Encrypt(rawPassword, out publicKey, out privateKey);
Assert.AreNotEqual(rawPassword, encryptedPassword,
"Raw password and encrypted password should not be equal");
// Decrypt
string decryptedPassword = RSAUtils.Decrypt(encryptedPassword, privateKey);
Assert.AreEqual(rawPassword, decryptedPassword,
"Did not get expected decrypted password");
Он дает сбой при расшифровке, но только иногда. Кажется, что всякий раз, когда я устанавливаю точки останова и выполняю тест, он проходит. Это заставило меня подумать, что, возможно, что-то не закончилось вовремя для успешного расшифрования, и то, что я замедлил пошаговое выполнение во время отладки, дало достаточно времени для завершения. Когда он терпит неудачу, строка, в которой он, кажется, терпит неудачу, является decryptedBytes = rsa.Decrypt(bytesToDecrypt, false);
в следующем методе:
public static string Decrypt(string textToDecrypt, string privateKeyXml)
{
if (string.IsNullOrEmpty(textToDecrypt))
{
throw new ArgumentException(
"Cannot decrypt null or blank string"
);
}
if (string.IsNullOrEmpty(privateKeyXml))
{
throw new ArgumentException("Invalid private key XML given");
}
byte[] bytesToDecrypt = ByteConverter.GetBytes(textToDecrypt);
byte[] decryptedBytes;
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(privateKeyXml);
decryptedBytes = rsa.Decrypt(bytesToDecrypt, false); // fail here
}
return ByteConverter.GetString(decryptedBytes);
}
Это терпит неудачу с этим исключением:
System.Security.Cryptography.CryptographicException: неверные данные
Мой метод Encrypt
выглядит следующим образом:
public static string Encrypt(string textToEncrypt, out string publicKey,
out string privateKey)
{
byte[] bytesToEncrypt = ByteConverter.GetBytes(textToEncrypt);
byte[] encryptedBytes;
using (var rsa = new RSACryptoServiceProvider())
{
encryptedBytes = rsa.Encrypt(bytesToEncrypt, false);
publicKey = rsa.ToXmlString(false);
privateKey = rsa.ToXmlString(true);
}
return ByteConverter.GetString(encryptedBytes);
}
ByteConverter
, используемый повсюду, выглядит следующим образом:
public static readonly UnicodeEncoding ByteConverter = new UnicodeEncoding();
Я видел несколько вопросов на StackOverflow о шифровании и дешифровании RSA с помощью .NET. Это было связано с шифрованием с помощью закрытого ключа и попыткой расшифровать с помощью открытый ключ, но я не думаю, что делаю это. Этот вопрос имеет то же исключение, что и я , но выбранный ответ заключался в использовании OpenSSL.NET, чего я бы предпочел не делать.
Что я делаю неправильно?