7

It's a well known fact that C# string is pretty insecure, it's not pinned in RAM, the Garbage Collector can move it, copy it, leave multiple traces of it in RAM and the RAM can be swapped and be available as a file to be read, not mentioning several other known facts.

In order to mitigate this Microsoft came up with SecureString. The thing is: what is the proper way of using it?

I ask this because sooner or later you will have to extract the inner string. And yes, SecureString does allow us to write one char at a time and gives us some other minor usages while hiding it's secret, but sometimes we need the whole string at once or something like it. So far all implementations I see use a regular string at the end, with the extracted and decrypted content from the SecureString which I think (or hope) it's avoidable in some cases even though it might involve some complicated code to get around a .NET string.

In my case I use a library for password hashing called BCrypt. It uses a regular string for calculating the hashes, which I think is far from ideal. I didn't find any libraries that would accept a SecureString directly, so I don't have much of an option but use it.

Currently I run code such as this:

SecureString password; // This usually comes from a PasswordBox Property
IntPtr passwordBSTR = Marshal.SecureStringToBSTR(password);

string insecurePassword = Marshal.PtrToStringBSTR(passwordBSTR);
Marshal.ZeroFreeBSTR(passwordBSTR);
passwordBSTR = default(IntPtr);
password.Clear();

// Use the insecurePassword....usually as:
bool result = BCrypt.Net.BCrypt.Verify(insecurePassword, user.Password); // This hashes the provided password and compares it with another BCrypt hash.

insecureString = string.Empty; // hoping for the GC to act now, fingers crossed.

// use result and etc...

This way the password raw string will be copied multiple times for the BCrypt method and probably even more times inside it.

This makes some questions arise in my mind:

1 - Are BSTR strings like C strings in the sense of memory management? Are they pinned in RAM and I can manipulate them and erase them as I see fit so it will be more secure to use them in C# or interop it with a C++ code so I can eliminate a lot of my .NET string manipulations (like verifying if the password string is null or white space or has the correct length or has the desired password strength)?

2 - If question's #1 answer is "yes" then should I invest some time to pass the BSTR string to a interop C++ code to calculate it's hash and verify?

3 - Is my later code correct or am I missing something on SecureString manipulation?

Just to be clear: My main intent with this question is to evaluate if I should pass all my password handling code to C++ from my C# (probably using C++/CLI or interop) to achieve a more secure code than what C# has to offer. This scenario really concerns me for password string hashing were multiple strings will be created and copied with the user's secret information scattered all over the RAM.

As an example: I could make a method like:

public string SecureHash(SecureString password)

And this method will extract the SecureString value and pass it as a BSTR string (or other extraction option, I honestly don't know the benefits between them) to a C++ hashing method, so we can control all the places our password sits in memory.

I ask this to not have a huge work refactoring my code and in the end discover it was all for nothing because I was using SecureStrings wrongly all the time and there are already solutions for this, or a false sense of security, as it happens sometimes, since I am not aware of how BSTR strings are implemented in memory or the other SecureStrings extraction options (Unicode, ANSI and etc).

mFeinstein
  • 241
  • 4
  • 13
  • This question is too old to be migrated, but you could get more answers in [SO](http://www.stackoverflow.com). – Serge Ballesta Dec 22 '16 at 07:41
  • I already posted there, I did get some, but the conclusion is that there is a deficiency on this in C# and I have to make my own code. I intent to make a library when I have more free time. – mFeinstein Dec 22 '16 at 14:30

1 Answers1

1

It all depends on what you want to do.

Answer to the first part of your post:

There are .net implementations of secure string in the following: WPF's System.Windows.Controls.PasswordBox control keeps the password as a SecureString internally (exposed as a copy through PasswordBox::SecurePassword) The System.Diagnostics.ProcessStartInfo::Password property is a SecureString and finally X509Certificate2 takes a SecureString for the password.

Answer to the second part of your post:

If you want to get more into the internals of hashing, BCrypt/BCryptPrimatives/PBKDF2 are generally considered FIPS 140-2 compliant (A Government Standard) specifically because they do carefully handle hashing and passwords on disk and in memory.

If you really want to go into the nitty gritty (And it seems like you do...) Go here: http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1892.pdf

There are plenty of details about how this works in that PDF, sorry for the link, it's just too big of a subject to cover in a single post.

mumbles
  • 380
  • 1
  • 2
  • 12
  • I appreciate your time answering this, but I don't think you understood my question, so I edited it to try to be more clear. In the first part, I don't ask `Where can I find a SecureString in the .NET FrameWork` but rather how to use it once I have it. For example, after my user typed his password on a `PasswordBox` what now? How's the most secure way of manipulating it for a BCrypt as just an example. For the second part: I don't want to understand how BCrypt works, I never asked any of this, I just gave BCrypt as an example of intense `string` manipulation and something pretty common. – mFeinstein Sep 20 '16 at 05:14
  • I asked about memory behavior and if it's worth it or not to forget `string` entirely and go and interop for a C++ code using the `BSTR` that could be predictable and controllable (not subject to the GC) and hence A LOT more secure than the regular `SecureString` decryption. As as I can see making a C# secure password code can be very challenging for the lack of proper tooling and my goal is to explore other options to expand its safety. – mFeinstein Sep 20 '16 at 05:19