How do you store passwords securly, yet have access to them? (C#)

Kris

Gawd
Joined
Jun 27, 2004
Messages
618
I'm wondering how many applications, like IE, Opera, FireFox, etc store usernames and passwords.

I know you can just encrypt them, but then you need a key to unencrypt them which requires the user to input another password everytime they need to access a specific username and password (which none of the browsers do) or they can hard code the key into their code, which would be visible via resource editors or decompilers.

So, how do they do it? I need to let the user input some usernames and passwords into my applications and store then securly, yet be able to access the username and password themselves later on.

I know with .Net 2.0 I have access to the SecureString class but can you even serialize that so it keeps the string encrypted?
 
SecureString isn't about encryption. It's about wiping out the data in the string in a deterministic manner (instead of leaving it lying around in memory, where the garbage collector may or may not take care of it).

Look around in the System.Security.Cryptography namespace to find classes that will help you encrypt your data. RSACryptoServiceProvider is probably the class you want, but I'm not sure how .NET maps this space.

You might want to read the Cryptographic Tasks topic in MSDN for pointers to different tasks in sample code, and look through the Cryptography Overview to learn the lay of the land.

In native Win32, I'd use the CryptProtectData() and CryptUnprotectData() APIs. These will encrypt and decrypt the data using a key stored on the system within the cryptographic provider. If the data leaves the system, it is no longer associated with the key and inherently can't be decrypted.

If you try to use private key encryption for your password file, the problem is that anyone can figure out your key and use it to decrypt any password file they've copied or stolen and so on.
 
althought I am by no means an expert, when I was using coldfusion for storing passwords I would hash the password and store it in the database. I would then hash the users input and compare it to the hashed string, if they matched then they provied the right password
 
maxedoutcc said:
althought I am by no means an expert, when I was using coldfusion for storing passwords I would hash the password and store it in the database. I would then hash the users input and compare it to the hashed string, if they matched then they provied the right password
That's the method used if you do not need the original password. When firefox stores a password, it needs to store it in a manner that allows you to get the original back ( think: web forms and the like ).
 
XOR != OR said:
That's the method used if you do not need the original password.
As long as the hash is cyptographically secure. This is a pretty common failing.
 
mikeblas said:
SecureString isn't about encryption. It's about wiping out the data in the string in a deterministic manner (instead of leaving it lying around in memory, where the garbage collector may or may not take care of it).
According to the MSDN the SecureString is encrypted the entire time but yeah I know it's mainly for not making tons of Strings that the GC won't clean up. I just thought of the SecureString because it'll encrypt without requiring a key.
mikeblas said:
Look around in the System.Security.Cryptography namespace to find classes that will help you encrypt your data. RSACryptoServiceProvider is probably the class you want, but I'm not sure how .NET maps this space.

In native Win32, I'd use the CryptProtectData() and CryptUnprotectData() APIs. These will encrypt and decrypt the data using a key stored on the system within the cryptographic provider. If the data leaves the system, it is no longer associated with the key and inherently can't be decrypted.
I've looked through the namespace and even have done some simple cryptography. The problem with that and using those APIs is that they require using a key to decrypt everything and there is no way to securely store the key on the system.
mikeblas said:
If you try to use private key encryption for your password file, the problem is that anyone can figure out your key and use it to decrypt any password file they've copied or stolen and so on.
I know and this is my problem.

I just can't figure out how they store our passwords securely. I mean, with Opera and Firefox, you can use thumb drives to carry your data and it'll still have all of your passwords so it's not like it stores a key somewhere on your system. Since Firefox is open source and anyone can see the source code, I highly doubt they have an encryption key in their source code itself. I just don't see how they do it. It's like they are encrypting your passwords, securely, yet use no encryption keys to encrypt and decrypt.
 
Does SecureString ever expose the chiphertext? My understanding is that you set the plain text, and get the plain text back out of it. It's storing encrypted text, but I don't think the client of the class ever sees it.

Why not have a look at the Firefox source, then, and see how they're doing it?
 
mikeblas said:
Does SecureString ever expose the chiphertext? My understanding is that you set the plain text, and get the plain text back out of it. It's storing encrypted text, but I don't think the client of the class ever sees it.
SecureString does not expose the chiphertext. As I understand it, when it stores characters (it only accepts characters, no strings) it keeps it in encrypted memory. Getting it back out isn't as easy as getting it in though. This is how I get a String from a SecureString:

Code:
public static string SecureStringToString(System.Security.SecureString str)
{
    IntPtr bstr = Marshal.SecureStringToBSTR(str);
    byte b = 1;
    int i = 0;
    string s = "";
    while (((char)b) != '\0')
    {
        b = Marshal.ReadByte(bstr, i);
        i += 2;
        s += (char)b;
    }
    Marshal.FreeBSTR(bstr);
    return s;
}
Not quite as simple as you'd like to think but then again it was probably done by design.
mikeblas said:
Why not have a look at the Firefox source, then, and see how they're doing it?
I'm actually downloading it now. I've done a lot of C and C++ programming but almost nothing involving GUIs and other frameworks in C/C++ so let's see if I can figure it out :p
 
I've looked through much of the Firefox code and cannot find where they manage usernames and passwords. Ugh
 
If you can tell me where this feature is in the UI (eg, what do I do to copy out or copy back my usernames and passwords) I can try to help you find it.
 
mikeblas said:
If you can tell me where this feature is in the UI (eg, what do I do to copy out or copy back my usernames and passwords) I can try to help you find it.
With FireFox 1.5, when you go to any kind of form that requires a password (like if you went to log into vBull), after you type in your username and password it'll ask if you want FireFox to "remember" your password. After you select remember, whenever you go back to that form it'll automatically enter your username and password.

After you have it "remember" at least one password, you can also go to Tools -> Options -> Privacy -> Passwords and select "View Saved Passwords". If you click on the button you can click on another button that says "Show Passwords" that will reveal your password in the list of usernames.

Thanks
 
How do you have FireFox dump the list to a file? Or is it in that dialog? (I don't use FF, obviously.)
 
mikeblas said:
How do you have FireFox dump the list to a file? Or is it in that dialog? (I don't use FF, obviously.)
It's a dialog. I don't see any way to dump it into a file.

I've been searching myself and what I've found so far is:

  • All signon information appears to be saved into C:\Documents and Settings\<user>\Application Data\Mozilla\Firefox\Profiles\<bunch of random characters>\signons.txt. This file appears to have the username and password in the following format:
    Code:
    #2c
    .
    [url]http://www.websiteaddress.com/[/url]
    USERNAME
    bunch of gibberish here (possibly a bash?)/
    *Password
    bunch of gibberish here (possibly a hash?)
    .
  • There is a key3.db in the same location though I don't know if that's an encryption key or not.
  • I found the GUI components (the widgets) in the source under widgets\src\windows\ but I think it's basically all declared there but the objects are not created within those files so I haven't been able to find what it executes when it displays the list of passwords or when it saves any
 
Kris said:
It's a dialog. I don't see any way to dump it into a file.
I guess I'm confused -- you said that "you can use thumb drives to carry your data". How can I export that list to my thumb drive?
 
mikeblas said:
I guess I'm confused -- you said that "you can use thumb drives to carry your data". How can I export that list to my thumb drive?
The data is stored in the special folder under a username but you can run firefox from a thumb drive and your data will stay on the thumb drive itself.

You can use portable firefox or follow some directions to get a normal verison of firefox onto the thumb drive.

It basically makes it so it refers to relative paths for storing temporary files, profiles, passwords, etc...
 
Read DecrpytString() in extensions\wallet\wallet.cpp.

Apparently, there's a "master password" and a "SecretDecoderRing" interface. SecretDecoderRing provides the DecryptString() implementation.

DecryptString() is implemented in security\manager\ssl\src\nssdr.cpp. It calls Decode() (which I would assume just makes sure the characters are representable) and Decrypt().

Decrypt() is also in nssdr.cpp. It relies on a bunch of PK11 routines, which come from pk11func.h and pk11sdr.h.

And that's all the time I have.
 
Thanks a lot mike. I'll look into those files further for some ideas
 
Back
Top