Questo è il mio primo post, quindi spero di non aver perso nulla di importante. Sto facendo un progetto in C# in cui ho bisogno di utilizzare la crittografia a chiave pubblica/privata per crittografare un messaggio e quindi inviarlo tramite una connessione SSL.RSA Crittografia dei grandi dati in C#
Ho scelto di utilizzare RSACryptoService
, in base alla documentazione, che era l'unico schema di crittografia asimmetrico utilizzato per la crittografia dei dati. Il problema è che sto avendo molti problemi con questo. (Volevo fare la crittografia simmetrica, ma non è quello che il mio insegnante vuole che faccia, e secondo lui dovrebbe essere facile determinare solo una dimensione del blocco e poi dovrebbe fare tutto il lavoro per te.) Bene, finora senza fortuna e ho provato alcuni approcci diversi, ma ora sono tornato alle origini e provare di nuovo, questo è il mio codice corrente:
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;
}
Come potete vedere, ho generare le chiavi e ho mimmick una PKI inviando la chiave pubblica ad una semplice classe che la memorizza, e quindi la chiave privata viene scritta su un file (Si noti che ho anche un altro metodo che fa lo stesso ma lo memorizza invece su un array, solo perché volevo testare e semplificare le cose man mano che ottengo le eccezioni No such key exceptions
ea volte crittografiche quando eseguo il modo mostrato nell'ex ampia, così ho voluto semplificare semplicemente memorizzare la stringa rsa.ToXmlString
, come una stringa in un array, ma senza fortuna)
Ora ho un cifrare e metodo decifro come segue:.
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;
}
decrittografia :
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;
}
so che questo è un muro di testo, ma spero che mi può dare una mano perché ho sbattere la testa contro il muro per così tanto tempo ormai non è divertente :)
Il problema è, come posso fare per la crittografia dei messaggi con RSA
(o qualsiasi altro/crittografia a chiave privata pubblica)
Ecco il client di prova:
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);
}
Come ho già detto, gli array di stringhe sono lì perché volevo eliminare l'errore di analisi errato dai documenti XML ...
Quando eseguo il client di test, se uso la chiave privata per crittografare e la chiave pubblica per decodificare, ottengo una "chiave non esiste eccezione" e se lo faccio al contrario, ottengo un'eccezione di dati non validi.
Per favore aiutatemi ragazzi, se siete a conoscenza di una buona guida, o potete dirmi come implementare in qualche modo una cifratura della chiave pubblica/privata sui messaggi di stringa, per favore aiutatemi.
Apprezzo qualsiasi aiuto.
Ho parlato con il mio professore e in quel momento il mio punto di vista era che sarebbe stato meglio cifrare una chiave, scambiare la chiave e quindi usarlo come base per un algoritmo simmetrico, come rijndael per crittografare/decifrare il messaggio, tuttavia, non voleva che usassimo la crittografia simmetrica, quindi ora sono in una posizione in cui per ora è un po 'fuori limite. Per quanto riguarda le prestazioni, quanto tempo ci vorrebbe per crittografare i messaggi, 501 byte alla volta (usando le chiavi RSA 4096 bit) quando parlavamo di messaggi HTTP contenenti nome utente e password? codifica blocco per blocco o meno, ho ancora problemi con RSA :( –
È possibile eseguire il loop della crittografia/decodifica RSA per rimanere al di sotto del limite di dimensione (padding incluso) e concatenare/dividere il risultato. la tua CPU, è un vecchio smartphone e un nuovo server 8 core? ;-) ma molto più a lungo di un'alternativa corretta. – poupou
Mi piacerebbe avere tempo, ma al momento non riesco nemmeno a far funzionare tutto questo per nessun dato. Ho preso una versione semplificata e l'ho usata, tuttavia, ho ancora l'errore "La chiave non esiste" e tutto ciò che ho fatto è stato il refactoring del design, da un singolo metodo principale per separare i metodi. Forse sto usando il costruttore giusto? La parte in cui importare le impostazioni chiave? So che un cifrario a blocchi è 1000 volte più lento di un algoritmo simmetrico, ma in questo momento voglio solo farlo funzionare, non importa se devo hardcode in modo da tagliare ogni blocco di dati in pezzi di (keysize/8 - 11 (per riempimento)) byte. –