12

I'm writing a C# application that will be open source and I need to be able to store saved login information for each user. Normally I would just encrypt the password and then store it in a user settings file, but I worry that because of the code being open source it kind of defeats the point of encrypting it. Since all anyone would have to do is look at the code and grab the encryption key.

Granted, it would at least make it a lot harder than the password being stored in plain text. But is there any decent way of encrypting the password, but making it still at least extremely difficult to decrypt it even if you had the source? Maybe make it so it would at least be nearly impossible to decrypt on any computer other than the one it was encrypted on?

EDIT: Clarification... I'm storing CLIENT side passwords, NOT passwords to validate their login for the service. It's a client to a pre-existing web service of which I have no control. I just want to store the passwords locally for automatic login... like any chat client would.

EDIT 2: Totally sorry for not being clear before. But passwords have to be retrieved in clear text at some point and hashing is NOT an option :( Even if the service would let me pass the password hash that would kinda defeat the purpose because the hash would be as good as a password :P

Adam Haile
  • 30,705
  • 58
  • 191
  • 286

5 Answers5

7

What you are asking is basically, impossible.

There is no way to safely store a password on a client machine if it needs to be decrypted. This is further aggravated by the fact that you need it to connect to a service, which I presume does not support SSL. In this case, one could trivially find the password by using a network analyzer.

There is a game (closed source, of course) I play that requires a login, the password is saved somewhere but it's encrypted with a key that's unique to each install. I forgot the password once, so I just used Wireshark, and voila - I could see the plain password.

This also reminds me of people complaining about it being easy to reveal passwords in Google Chrome... They obviously don't know better. You can try all the clever tricks you want, but any application security is thrown out the window once someone has access to the machine.

So with this in mind, I would keep the encryption and decryption really simple. At best, you can create a key derived from something unique to the machine, so someone who steals the encrypted password will be unable to decrypt it without access to said unique key.

Community
  • 1
  • 1
NullUserException
  • 83,810
  • 28
  • 209
  • 234
  • Fortunately, the service DOES provide SSL. And yeah, I know the only totally secure way is to make the user enter the password EACH time, but I think most are willing to give up a little security for that. – Adam Haile Aug 31 '11 at 14:54
  • so provide some kind of token from the server with some kind of validity...it's not fireproof but it is as good as it can get – Maarten Bodewes Aug 31 '11 at 17:10
  • Please could you also mention some algorithm I could use to encrypt the password? – Tomáš Zato Mar 25 '15 at 23:02
4

If you are using this application in Windows you can use DPAPI for storing sensitive data on behalf of the user:

How To: Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)

Also storing the hash only instead of the full password is a good idea!

gyurisc
  • 11,234
  • 16
  • 68
  • 102
1

I think if you use Rijndal for instance and create random salt values and derive the keys from machine specific things (like some hardware IDs) it will be hard to decrypt, even if you know how it works because you are missing the information of the hardware.

But you might consider storing hashes of the passwords only and iterate at least 1000 times. Hashes cannot be covnerted back to the original password.

Yet another idea: would it maybe be an option to just leave the implementation up to who ever is going use your source and make the encryption abstract? Doesn't work of course if you offer a built bundle to download. But then again: in the build you could use your own "secret" encryption and stull have it abstract in the source.

Krumelur
  • 32,180
  • 27
  • 124
  • 263
  • Don't get what you mean about the hashes... I need the actual clear text of the password at some point because it has to be passed from my client to the service (which is an encrypted connection) and cannot be a hash. – Adam Haile Aug 31 '11 at 14:10
  • From the password you receive, just calculate the hash again and compare that to the hash you stored in the DB. If they match, the passwords match. Of course if you need the password to login somewhere else from your server, this won't help you. – Krumelur Aug 31 '11 at 14:12
  • 3
    He CHANGED the question in part, clarifying really, voting down is a ltitle unfair. – Lloyd Aug 31 '11 at 14:14
0

Yuo could use babushka doll encryption. You encryt the password with another password, then encrypt that with another password, and do that lots of times eventually writing the last password in clear text. Anyone who wants to get access to the orignal password will get sick of all the unencrypting and give up before they get to the original password.

oenpelli
  • 3,467
  • 2
  • 29
  • 20
0

Maybe you can encrypt password using some machine specific values, like mac or sth.. If someone get source and encrypted password but no full access to the machine password should be safe.

szamil
  • 684
  • 5
  • 17