Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe use of SecureString for login form

Tags:

So there's this class that seems very seldom used: SecureString. It's been around since 2.0 at least, and there are a few SO questions on it, but I thought I'd ask my own specific questions:

I have a LoginForm; simple WinForms dialog with username and (masked) password fields. When the user enters both and clicks "Login", the information is passed to an injected authentication class that does a layer of key-stretching, then hashes half of the stretched key for verification while the other half is the symmetric key for the encrypted user account data. When all this is through, the loginForm is closed, the authenticator class disposed, and the system moves on to loading the main form. Pretty standard stuff, maybe a little more involved than the standard hash-the-password-and-compare, but the simple hashed password would be defeated in my case by storing the user data in plaintext, because that data includes credentials for a third-party system (and we all know how people like to reuse passwords).

Here's the first question; how would I use SecureString to retrieve the password from the Password textbox, without it being exposed as an ordinary System.String through the Text property of the textbox? I assume there's a way to access the unmanaged GDI window for the Textbox that's being wrapped by the CLR classes, and pull the text data in using the Marshal class. I just don't know how, and I can't seem to find good information.

Here's the second question; once I have the password as a SecureString, how do I pass it to a hash provider from the System.Security.Crypto namespace? My guess is that I'd use Marshal.SecureStringToBSTR(), then Marshal.Copy() from the returned IntPtr back into a byte array. I can then call Marshal.ZeroBSTR() to clean up the unmanaged memory and I can zero out the managed array with Array.Clear() once I have the hash. If there's a cleaner way that allows me full control over the lifetime of any managed copy of the memory, do tell.

Third question; Is all this really necessary, or is the inherent insecurity of System.String in a managed-memory environment a little overblown? Anything used to store the password, encrypted or otherwise, should be out of scope and on its way to the garbage collector long before the OS would consider swapping the app into virtual memory (allowing the password to be sniffed from the swap-file after a hard shutdown of the computer). A cold-boot attack is a theoretical possibility, but really, how common is this? The bigger concern is the now-decrypted user data, which hangs around as part of the user for the entire application lifetime (and thus would be a prime candidate for using SecureStrings, as except for a couple of basic usages they stay pretty dormant).

like image 889
KeithS Avatar asked Jan 22 '13 00:01

KeithS


People also ask

Is SecureString secure?

Overall, SecureString is more secure than String because it limits the exposure of sensitive string data. However, those strings may still be exposed to any process or operation that has access to raw memory, such as a malicious process running on the host computer, a process dump, or a user-viewable swap file.

Which method is secure to send password?

Send passwords in a password vault file such as KeePass. This application lets you to store usernames, passwords, addresses and notes in a single file. Which happens to be both encrypted and password protected. Then, communicate the password to the vault by one of the above methods.

What are secure strings in powershell?

Specifies a plain text string to convert to a secure string. The secure string cmdlets help protect confidential text. The text is encrypted for privacy and is deleted from computer memory after it is used. If you use this parameter to provide plain text as input, the system cannot protect that input in this manner.

How are passwords transmitted?

When the user enters a password, this is sent over the network and hashed on the server using a copy of the same hashing function. The resulting hash is compared to the hash stored on the password server. Only if they match will the user be granted access.

What is the use of securestring class?

The SecureString class has only two members that provide information about the string: its Length property, which indicates the number of UTF16-encoded code units in the string; and the IsReadOnly, method, which indicates whether the instance is read-only.

Why can't I Just Say securestring password = new securestring ()?

their cleanup is at the mercy of the garbage collector SecureString exists as a way to pass around strings safety, and be able to guarantee their cleanup when you need to. You asked the question: why can't I just say: SecureString password = new SecureString("password"); Because now you have passwordin memory; with no way to wipe it.

Is it possible to use securestring with the NET Framework?

However, outside of the .NET Framework itself, no usage mechanism supports SecureString. This means that the secure string must be converted to a usable form (typically a clear text form) that can be recognized by its target, and that decryption and conversion must occur in user space.

Can I use a securestring in an Interop call?

If the secure string is used in an interop call, it must be converted to an ANSI string, a Unicode string, or a binary string (BSTR). For more information, see the SecureString and interop section. The time interval for which the SecureString instance's value is exposed is merely shortened in comparison to the String class.


2 Answers

If you believe that you need SecureString you must believe that an attacker can read your process memory, too. If the latter is true he can read the password characters as they are typed, or read from the textbox internal character buffer directly, or read pixels off the screen.

This is an unrealistic scenario. Don't use SecureString. It helps little and steals your time.

Cold boot attacks are more real, yet extremely uncommon. They require physical machine access which usually totally owns the machine. Reading by the attacker is the least of your concerns in this case.

Basically, you have to contrive a case where your developer time is well spent using SecureString.

like image 98
usr Avatar answered Nov 08 '22 11:11

usr


First of all, I'd like to state that I agree with usr - don't bother.

Now to the details:

  • This answer provides great background for the discussion.
  • This is a TextBox control that utilises SecureString. I have not used this so I can't comment on the quality, but being on MS blog I don't expect it to be anything but proper.
  • To answer the question about passing the data to System.Security.Crypto, basically you can't and no amount of unmanaged memory marshalling will help you, since during the process of such marshalling the string gets decrypted. It has to because otherwise it can't be consumed by your target API. If you are using CSP or X509Certificate, you can use SecureSctring because these are supported in the framework, but that's about it.
like image 22
Andrew Savinykh Avatar answered Nov 08 '22 11:11

Andrew Savinykh