Estoy intentando cifrar y descifrar datos utilizando RSA en C#. Tengo la siguiente prueba de unidad MSTest:CryptographicException se produce de forma intermitente al cifrar/descifrar con RSA
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");
Se produce un error durante el descifrado, pero solo algunas veces. Parece que cada vez que establezco puntos de interrupción y paso por la prueba, pasa. Esto me hizo pensar que tal vez algo no estaba terminando a tiempo para que la descifración ocurriera con éxito, y que me ralentizé mientras la depuración le daba tiempo suficiente para completarla. Cuando falla, la línea parece fallar en es decryptedBytes = rsa.Decrypt(bytesToDecrypt, false);
en el siguiente método:
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);
}
falla con esta excepción:
System.Security.Cryptography.CryptographicException: Datos incorrectos
Mi método Encrypt
es el siguiente:
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);
}
El ByteConverter
utilizado a lo largo es sólo el siguiente:
public static readonly UnicodeEncoding ByteConverter = new UnicodeEncoding();
que he visto algunas preguntas sobre stackoverflow sobre cifrado RSA y descifrado con .NET. This one se debió a la encriptación con la clave privada y al intento de descifrado con la clave pública, pero no creo que esté haciendo eso. This question tiene la misma excepción que yo, pero la respuesta seleccionada fue usar OpenSSL.NET, que yo preferiría no hacer.
¿Qué estoy haciendo mal?
Hm, lo que me da una excepción diferente: "System.FormatException: longitud no válida para una matriz de caracteres Base-64". Esto ocurrió en la primera línea de 'Encrypt':' byte [] bytesToEncrypt = Convert.FromBase64String (textToEncrypt); '. –
@Sarah - Ok, actualicé su ejemplo. Lo probé y parece que funciona. – SwDevMan81
¡Eso funciona! Gracias. Nunca hubiera pensado usar esa mezcla de 'Convert' /' UnicodeEncoding'. –