Abbiamo password per determinati sistemi esterni che dobbiamo usare programmaticamente per accedere a quel sistema. Non abbiamo alcun controllo sul sistema esterno, non possiamo usare la password e usarla in quel modo, quindi a un certo punto abbiamo bisogno della password in chiaro. La password è attualmente memorizzata in un file xml in testo semplice. Non può essere codificato nel programma perché esistono più istanze di differenza di quel sistema esterno con password diverse e altre vengono aggiunte / rimosse / modificate spesso. Per fornire almeno un livello di protezione, vogliamo (simmetrico) crittografare quella password e inserirla nel file xml crittografato in quel modo e decrittografarlo nel programma quando lo si utilizza (che non è ancora una protezione completa, lo sappiamo, ma è almeno qualcosa). La soluzione deve funzionare senza Internet in qualsiasi momento, non puoi affidarti a nessun servizio pubblico / online.
Quale sarebbe il miglior algoritmo di crittografia per farlo? Stavo per utilizzare AES RFC2898 con keygen nb di iterazioni 100, keysize 128 e PKCS7 padding. L'implementazione .NET è in fondo a questo post. È una scelta sufficientemente sicura per l'uso previsto?
La chiave di crittografia sarebbe hardcoded nel programma che naturalmente non è buona, perché se decompilano il programma potrebbero vedere la chiave o potrebbero vederla nella RAM. Tuttavia, in realtà non vedo un'alternativa a questo: se vuoi memorizzare quella password da qualche altra parte, allora vuoi criptarla e poi torniamo a quanto sopra. O sbaglio e c'è un'alternativa?
Considerando che la chiave di crittografia sarà hardcoded dovrei usare un salt con la crittografia? Il sale aggiungerà ulteriore sicurezza aggiuntiva se è anche codificato come la chiave di crittografia? Se no potrei anche lasciare il sale bianco?
string textToEncrypt= "thepasswordtoencryptwillbeputhere";
int Rfc2898KeygenIterations = 100;
int AesKeySizeInBits = 128;
string EncryptionKey = "encryptionkeywillbehardcodedhere";
byte[] Salt = new byte[16];
byte[] rawPlaintext = System.Text.Encoding.UTF8.GetBytes(textToEncrypt);
byte[] cipherText = null;
using (Aes aes = new AesManaged())
{
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = AesKeySizeInBits;
int KeyStrengthInBytes = aes.KeySize / 8;
System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 =
new System.Security.Cryptography.Rfc2898DeriveBytes(EncryptionKey, Salt, Rfc2898KeygenIterations);
aes.Key = rfc2898.GetBytes(KeyStrengthInBytes);
aes.IV = rfc2898.GetBytes(KeyStrengthInBytes);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(rawPlaintext, 0, rawPlaintext.Length);
}
cipherText = ms.ToArray();
}
Console.WriteLine("Done, encrypted password:");
string encryptedPassword = Convert.ToBase64String(cipherText);
// ...
}