Tenemos contraseñas para ciertos sistemas externos que debemos usar mediante programación para iniciar sesión en ese sistema. No tenemos control sobre el sistema externo, no podemos copiar la contraseña y usarla así, por lo que necesitamos la contraseña de texto simple en algún momento. La contraseña se almacena actualmente en un archivo xml en texto plano. No se puede codificar en el programa porque existen varias instancias diferentes de ese sistema externo con una contraseña diferente y muchas más se agregan / eliminan / cambian a menudo. Para al menos proporcionar alguna capa de protección, queremos cifrar (simétricamente) esa contraseña y ponerla en el archivo xml cifrado de esa manera, y descifrarla en el programa cuando se usa (lo que aún no es una protección completa, lo sabemos, pero es al menos algo). La solución debe funcionar sin Internet en todo momento, no puede confiar en ningún servicio público / en línea.
¿Cuál sería el mejor algoritmo de cifrado para hacer eso? Iba a utilizar AES RFC2898 con keygen nb de iteraciones 100, tamaño de clave 128 y PKCS7. La implementación de .NET está al final de esta publicación. ¿Es esta una opción suficientemente segura para el uso previsto?
La clave de cifrado estaría codificada en el programa, lo que, por supuesto, no es bueno, ya que si descompilan el programa podrían ver la clave o podrían verla en la RAM. Sin embargo, realmente no veo una alternativa a eso: si desea almacenar esa contraseña en otro lugar, entonces desea cifrarla y luego volveremos a lo anterior. ¿O me equivoco y hay una alternativa?
Teniendo en cuenta que la clave de cifrado estará codificada de forma rígida, ¿debo utilizar un salt con el cifrado? ¿Agregará Salt la cantidad de seguridad adicional si también está codificada como la clave de cifrado? Si no, ¿podría dejar la sal en blanco?
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);
// ...
}