As already mentioned, a security issue is rarely simple . However, if you need to have data in memory without it being visible, do not use any temporary / fixed variable for storage before encryption.
On the face of it, this involves a somewhat more specific problem that is how memory management is done in .NET. So if you use a string variable, it will be stored until the GC decides it is no longer useful and you have no control over when it will be deallocated.
There are several articles on this, try this:
link
Also, why do you need to start the string in a plain text variable? If you are going to use it, you could at least use it in a SecureString , see this link:
link
But, there also involves how much a SecureString is secure :)
The biggest problem is how you pick up the string and how your encryption works. But at some point it will go through the memory to be encrypted.
You could use unmanaged code to better control how long it stays in memory, but unmanaged code has other security issues, many of which are linked to memory management or program execution flow.
There is no silver bullet. Even a char, typed on the keyboard, has to go through a buffer, just try to ensure that the place where you put the plain text, exists in the shortest possible time and is never stored in a long-lasting scope.
See the difference in the code example of the SecureString link:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security;
public class Example
{
public static void Main()
{
// Instantiate the secure string.
SecureString securePwd = new SecureString();
ConsoleKeyInfo key;
Console.Write("Enter password: ");
do {
key = Console.ReadKey(true);
// Ignore any key out of range.
if (((int) key.Key) >= 65 && ((int) key.Key <= 90)) {
// Append the character to the password.
securePwd.AppendChar(key.KeyChar);
Console.Write("*");
}
// Exit if Enter key is pressed.
} while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
try {
Process.Start("Notepad.exe", "MyUser", securePwd, "MYDOMAIN");
}
catch (Win32Exception e) {
Console.WriteLine(e.Message);
}
finally {
securePwd.Dispose();
}
}
}
The main difference is that it does not save a plaintext string and then move on to encryption, it already adds char to the char to the encrypted string.
Another thing he does is that he overrides each char with each new character entered, so only SecureString contains the whole sequence in memory, but the current char remains in memory for as long as the scope and GC allow .
This particular case of analysis, at first glance, seems to only serve a char to char entry by the console, however, you should remember that it can be applied to the stream stream by any byte-by-byte, not forgetting hidden buffers in the implementation of most standard APIs.
In addition, if the machine is compromised, even this approach falls easily on a Keylogger. :