Thanks, so far I am just using it to encrypt an object storing data (like a list) then storing the serialized EncryptedObject to the disk. The password would always be entered manually into a textbox in a form then sent to the function.
I can't see anyway to secure the data or password when it is held in memory (SecureString seems like a real pain/impossible to use for most situations)
It was just making sure what I have done is reasonably secure. Like if encrypting serialized objects might be a bad idea, or (like I have seen in some tutorials) generating the IV from the password. Or using PasswordDerivedBytes instead of Rfc2898DeriveBytes.
However I didn't realise you could have multiple using statements for one scope, that is really nice
Well ultimately, the plaintext has to be in memory at some point, otherwise you won't be able to do anything with it. The problem with keeping it secure is how long it stays in memory and how it is manipulated once there. Unfortunately, since the CLR is a managed environment, you have no control over exactly what goes on on the managed heap (i.e. the block of memory managed by the CLR). Objects may be moved around on the heap, leaving residue where they used to be, and you have no control over when objects are removed (besides, the memory is not actually guaranteed to be 'erased' – until something takes its place, the original data remain there). In addition to this, .NET's
String class is immutable, so modifying a string only creates a copy, leaving the old one in memory until garbage collected.
Consequently, if it is to be secure, the plaintext must be stored on the unmanaged heap, where you have direct control over it. Essentially, what you want to do is allocate the memory, put the plaintext there, operate on the plaintext, and then overwrite it immediately afterwards so as to minimise the possibility of someone reading the memory.
This is all fine and dandy, except you can't use any kind of managed data structure (specifically reference types, e.g. strings, arrays, etc.) if you're dealing with the unmanaged heap; you must instead work with raw binary, either via the
Marshal class or using pointers, which requires unsafe code. (For the purposes of secure representations of objects, any value type can also be used, as these are stored on the stack, which is not managed, unlike the heap, but can also be stored on the unmanaged heap and accessed by way of pointers).
Because of this, you're very limited in what you can do with secure representations of objects in the FCL, as the vast majority of it uses only managed types. In the case of
PasswordDerivedBytes and
Rfc2898DeriveBytes, the password must be specified as either a string or an array of bytes (both of which are allocated on the managed heap).
That said, however, you really shouldn't worry about having the password in memory unless you're deploying your application in an environment that you do not trust, and even then you'd be being overly paranoid unless the data you're trying to protect are very sensitive (which in an untrustworthy environment would be a very unusual scenario anyway).
That was probably a huge waste of typing and brain power, but hey, I found it interesting
