Esta es mi primera publicación, así que espero no haberme perdido algo importante. Estoy haciendo un proyecto en C# donde necesito usar un cifrado de clave pública/privada para encriptar un mensaje y luego enviarlo a través de una conexión SSL.Cifrado RSA de datos grandes en C#
Opté por usar el RSACryptoService
, ya que de acuerdo con la documentación, ese era el único esquema de cifrado asimétrico utilizado para encriptar datos. El problema es que estoy teniendo muchos problemas con esto. (Quería hacer un cifrado simétrico, pero eso no es lo que mi maestro quiere que haga, y según él, debería ser fácil determinar el tamaño de un bloque y luego debería hacer todo el trabajo por usted). Bueno, hasta ahora sin suerte y he probado algunos enfoques diferentes, pero ahora estoy de vuelta a lo básico y volver a intentarlo, esta es mi código actual:
public string[] GenerateKeysToStrings(string uniqueIdentifier)
{
string[] keys;
using (var rsa = new RSACryptoServiceProvider(4096))
{
try
{
string privateKey = rsa.ToXmlString(true);
string publicKey = rsa.ToXmlString(false);
this.pki.StoreKey(publicKey, uniqueIdentifier);
keys = new string[2];
keys[0] = privateKey;
keys[1] = publicKey;
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return keys;
}
Como se puede ver, genero las llaves y yo mimmick una PKI enviando la clave pública a una clase simple que la almacena, y luego la clave privada se escribe en un archivo (Observe que también tengo otro método que hace lo mismo pero lo almacena en una matriz, simplemente porque quería probar y simplificar las cosas a medida que obtengo No such key exceptions
y, a veces, excepciones criptográficas cuando lo hago de la manera que se muestra en el ex amplia, así que quería simplificarlo simplemente almacenar la cadena rsa.ToXmlString
, como una cadena en una matriz, pero no hubo suerte)
Ahora tengo una cifrar y descifrar el método de la siguiente manera:.
public string Encrypt(string keyString, string message)
{
string encryptedMessage;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Load the key from the specified path
var encryptKey = new XmlDocument();
encryptKey.Load(@"C:\Test\PrivateKeyInfo.xml");
rsa.FromXmlString(encryptKey.OuterXml);
//// Conver the string message to a byte array for encryption
//// var encoder = new UTF8Encoding();
ASCIIEncoding byteConverter = new ASCIIEncoding();
byte[] dataToEncrypt = byteConverter.GetBytes(message);
byte[] encryptedData = rsa.Encrypt(dataToEncrypt, false);
//// Convert the byte array back to a string message
encryptedMessage = byteConverter.GetString(encryptedData);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return encryptedMessage;
}
descifrado :
public string Decrypt(string keyString, string message)
{
string decryptedText;
using (var rsa = new RSACryptoServiceProvider())
{
try
{
//// Loads the keyinfo into the rsa parameters from the keyfile
/*
var privateKey = new XmlDocument();
privateKey.Load(keyString);
*/
rsa.FromXmlString(keyString);
//// Convert the text from string to byte array for decryption
ASCIIEncoding byteConverter = new ASCIIEncoding();
var encryptedBytes = byteConverter.GetBytes(message);
//// Create an aux array to store all the encrypted bytes
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, false);
decryptedText = byteConverter.GetString(decryptedBytes);
}
finally
{
//// Clear the RSA key container, deleting generated keys.
rsa.PersistKeyInCsp = false;
}
}
return decryptedText;
}
sé que este es un muro de texto, pero espero que usted me puede ayudar a cabo porque he estado golpeando mi cabeza contra la pared durante tanto tiempo que no es gracioso :)
El problema es, ¿cómo hago para el cifrado de mensajes con RSA
(o cualquier otro cifrado de clave pública/privada)
Aquí es el cliente de prueba:
public static void Main(string[] args)
{
PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
Cryptograph crypto = new Cryptograph();
string[] keys = crypto.GenerateKeysToStrings("[email protected]");
string plainText = "Hello play with me, please";
string publicKey = crypto.GetPublicKey("[email protected]");
string encryptedText = crypto.Encrypt(keys[0], plainText);
string decryptedText = crypto.Decrypt(keys[1], encryptedText);
}
Como ya he mencionado, las matrices de cadenas están ahí porque quería eliminar el error de análisis incorrecto de documentos XML ...
Cuando ejecuto el cliente de prueba, si uso la clave privada para encriptar y la clave pública para descifrar, obtengo una "Clave no existe excepción" y si lo hago al revés, recibo una excepción de datos erróneos.
Por favor, ayúdenme chicos, si conocen alguna buena guía, o pueden decirme cómo implementar algo de encriptación de clave pública/privada en mensajes de texto, por favor ayúdenme.
Agradezco cualquier ayuda.
Hablé con mi profesor y en ese momento mi punto de vista era que sería mejor cifrar una clave, cambiar la clave y luego utilícelo, como base para un algoritmo simétrico, como rijndael para cifrar/descifrar el mensaje; sin embargo, no quería que usáramos cifrado simétrico, así que ahora estoy en una posición en la que por ahora está fuera de límite. En lo que respecta al rendimiento, ¿cuánto más tiempo lleva cifrar mensajes, 501 bytes por vez (utilizando claves RSA de 4096 bits) cuando hablamos de mensajes HTTP que contienen nombre de usuario y contraseña? codificación bloque por bloque o no, todavía tengo problemas usando RSA :( –
Puede enuclear el cifrado/descifrado RSA para mantenerse por debajo del límite de tamaño (relleno incluido) y concatenar/dividir el resultado. ¿Cuánto tiempo? eso dependerá de su CPU, ¿es un teléfono inteligente antiguo y un nuevo servidor de 8 núcleos? ;-) pero mucho más que una alternativa correcta. – poupou
Ojalá pudiera cronometrarlo, pero ahora mismo no puedo hacer que esto funcione para ningún dato. Tomé una versión simplificada y usé eso, sin embargo, sigo teniendo el error "La clave no existe" y todo lo que realmente hice fue refactorizar el diseño, desde un solo método principal hasta métodos separados. Tal vez estoy usando el constructor ¿verdad? ¿La parte donde importo las configuraciones clave? Sé que un cifrado en bloque es 1000 veces más lento que un algoritmo simétrico, pero en este momento solo quiero que funcione, no importa si tengo que codificarlo para que corte cada bloque de datos en partes de (tamaño de clave/8 - 11 (para relleno)) bytes. –