Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SecureString password stored in database [duplicate]

I believe I'm misunderstanding a fundamental part of SecureString. I understand that string's are immutable and there a password or sensitive data is found as clear text on the heap.

What I'm struggling to understand is, how do I use SecureString in a client application which needs to verify the hashed password in a database?

Here's my context:

  • I'm using a WPF client application.
  • I have a local SQL database (on the client's machine)
  • The passwords are hashed and stored in the database.
  • The user tries logging into to my WPF application
  • The PasswordBox control stores the password in a SecureString via the SecurePassword property.

Now what? How do I hash a SecureString WITHOUT casting it back into string first?

All the advise I've received so far is to write extension methods converting SecureString to String, hash it and then send it to db to verify. But this defeats the whole exercise!

Must I just accept that SecureString is useless in my mentioned context and use plain string?

like image 639
Niels Filter Avatar asked Jun 03 '15 11:06

Niels Filter


1 Answers

SecureString is represented as a byte[] you could encode the bytes e.g. with bitconverter and save the result. Furthermore SecureString is a encryption not a hash as it can be decrypted. (see below)

SecureString mainly meant to store sensitive data in memory. If you have a service / website, this is not as important as the values which are stored in the database. These should never be plaintext, and imo not be decryptable by your or any administrator Also i'm not sure wether another server could decrypt the strings, so you may have a problem when you change the server or have somekind of cluster scenario.

Especially for passwords would prefer using hash algorithms (e.g. SHA256) . These can't be uncrypted (like the sum of the digits). In the use case of a login funtionality you would encrypt the userinput and compare the hashs the user and and the one thats in the database. (details se below) I would also suggest to add a dynamic criteria like the userid to the hashinput so that 2 user with same password would have different hashes.

With this strategy you don't have a risc with userpasswords and therefore if data gets leaked it wouldn't be a problem at this point.

Here an short overview of using hash algorithms

So ( if the securestring is given) first decrypt the SecureString

String SecureStringToString(SecureString value){
  IntPtr valuePtr = IntPtr.Zero;
  try{
    valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
    return Marshal.PtrToStringUni(valuePtr);
  }
  finally{
    Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
  }
}

Than hash it for example with SHA256. From this post

  using (SHA256 hash = SHA256Managed.Create()) {
    Encoding enc = Encoding.UTF8;

    //the user id is the salt. 
    //So 2 users with same password have different hashes. 
    //For example if someone knows his own hash he can't see who has same password
    string input = userInput+userId;
    Byte[] result = hash.ComputeHash(enc.GetBytes(input));

    foreach (Byte b in result)
      Sb.Append(b.ToString("x2")); //You could also use other encodingslike BASE64 
  }

Store this hashsum. Depending on your encoding it may looke like this:

ac5b208b4d35ec79fa7c14b7a31f9c80392cdab2bc58bc5b79bcfe64b044d899

in your database. If the user signs on then create the hash from his input and compare it with the hash in the database. if they are equal then the password is correct. Therefore you never need to have the plaintext user password anywhere stored.

If the client makes the hash then it should absolut should no where exist as a plaintext (except the textbox if it doesnt support the securestring)

PS: this is only one option. But the main thing is to never store plaintextpasswords anywhere. For best never know them and have no change to get them decrypted.

Another strategy would be to use asymmetric encryptions like RSA but this can become more complex. If you need help with that i would recommend a dedicated post on this.

Depending on your requirements and envionment most of the time hashsums should be an acceptable solution. (But thats not an legal advice as i'm not a lawyer)

like image 142
Boas Enkler Avatar answered Oct 16 '22 21:10

Boas Enkler