5

I'm going to be receiving a username and password and storing it in a struct.

What can I do to prevent someone from viewing the memory for my process and seeing the users username/password?

My first idea was to encrypt the username and password in memory, and zero it when i'm done with it. But then I would have to store a key somewhere in memory, which could be retrieved.

Well that would make recovering the credentials very difficult, it's still possible.

Is there any safer method than this?

Josh
  • 6,046
  • 11
  • 52
  • 83
  • 2
    Once an attacker has access to the machine all bets are off. The best you can do is take steps to secure the machine itself. – NotMe Mar 22 '13 at 15:23
  • 4
    Usually passwords are hashed, not encrypted. In which case, there is no key... – Oliver Charlesworth Mar 22 '13 at 15:29
  • How are you going to use those creds? The solution usually depends on the scenarios how you use them. – Valeri Atamaniouk Mar 22 '13 at 15:29
  • if you are accepting a password then you would usually store a hash and compare hash of the input password to the stored hash (ie don't store the password in the first place). If you're storing a password to provide to another service then it's another matter – msam Mar 22 '13 at 15:29
  • @msam that's exactly what i'm doing, storing the password to provide to another service. – Josh Mar 22 '13 at 15:30
  • one possibility is to encrypt the password with a second key (which is in turn not stored but hashed) - this would be used, for instance, in a password manager - however someone with access to the memory would still be able to get the password – msam Mar 22 '13 at 15:34
  • If the guy don't want to crack your application, you use plain-text password is OK. Otherwise there is no way to protect it entirely. My suggestion is that you write a script to run in your server and modify the password after you use it. – xjdrew Mar 22 '13 at 15:45

3 Answers3

3

Take a look at the Data Protection API. It's used by Windows components as well as third-party software for exactly this kind of scenario, and basically handles the encryption and key management for you.

Keys are tied to the current user's password, but you can supply "optional entropy", which is effectively a per-operation source of extra key material, which might e.g. be derived from a password entered by the user to secure the service credentials.

As for "is there any method safer than this", I think you need to define exactly what level of threat you're trying to protect against. For other (non-admin) users on the same machine, DPAPI is probably perfectly fine, along with things you've already mentioned like securely zeroing plaintext. For malicious software running in the same login session, very little will help you.

anton.burger
  • 5,637
  • 32
  • 48
  • And then, if the kernel debugger is in use, sessions and many other things become no more than an annoyance. – Alexey Frunze Mar 22 '13 at 16:15
  • @AlexeyFrunze the data protection API uses the user's session password to encrypt the data so from the kernel debugger (if that user is not logged on) you would only see the encrypted data but would still require the original user's password to decrypt it. If the user is logged on, then, as said by shambulator it can be retrieved – msam Mar 22 '13 at 16:26
2

The simplest solution would be to scatter the password around in memory. Don't store it as a string. Declare a set of byte variables and scatter the password among them. This doesn't make the password irretrievable, but it makes it difficult... the attacker needs access both to the computer and to your source (or reverse engineering your binary) to discover how and where the bits of the password are stored.

If the attacker has access to your system and your source, or the ability to reverse your binary, you'd be just as well off to e-mail him the passwords.

The more likely angle of attack in your scenario would be to grab the password in the act of being passed to the service than to try and assemble it from memory.

EDIT: If you want to significantly increase the difficulty of gathering the password, you could use dynamic memory allocation, as well, to prevent the bits from having a fixed location in memory. But, honestly, that's overkill... it would be just as easy for the attacker to snag the password when you're passing it to the service.

K Scott Piel
  • 4,320
  • 14
  • 19
  • Basic assumption in modern cryptography is that "*security by obscurity*" (like you suggest) isn't good enough and "*security by design*" is much better. – SomeWittyUsername Mar 22 '13 at 15:54
  • I don't disagree -- but given the constraint laid out by the OP, obscurity is better than nothing. That said, I agree... the design is flawed. – K Scott Piel Mar 22 '13 at 16:05
0

Hash the password with a good function (e.g. SHA1/2) and store the digest. When you want to check the password against the stored one, hash the input and compare the result with the stored one.

Basic property of a cryptographic hash function is that it's a one-way function: it's very hard to compute the inverse function. That's the reason these functions are used in situations such as your's.

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
  • The OP has indicated in the comments that they need the raw password because they send it to another party. You can't send a hash of it. – Alexey Frunze Mar 22 '13 at 15:54
  • @AlexeyFrunze Oh, I see it now. In this case the design sounds flawed to me. There shouldn't be multiple points of decision regarding the password validity or other manipulation – SomeWittyUsername Mar 22 '13 at 16:01
  • @icepack any application that logs the user into a third party service must do this one way or another - think saved rdp connections/password manager/saved passwords in browser etc – msam Mar 22 '13 at 16:06
  • @msam that doesn't mean the password has to be transferred openly; if not possible to protect the password itself, the protection should be at higher level (the complete session, for example). – SomeWittyUsername Mar 22 '13 at 16:11
  • You may use SSL and what not, but still, at some point the password is needed in the raw. – Alexey Frunze Mar 22 '13 at 16:13
  • @AlexeyFrunze SSL provides the necessary security and problem doesn't exist – SomeWittyUsername Mar 22 '13 at 16:20
  • @icepack the password is needed in cleartext at some point, it can be transferred over SSL but someone (the OPs application) needs to know it before encapsulating into SSL. - Again, think chrome password manager - the user can retrieve all the saved passwords using 3rd party applications, they are stored encrypted and possbily sent over the internet via SSL but if that key (the logon credentials) is known they can be retrieved in plaintext. There is no foolproof way to do what the OP wants, yet it is done by various applications. – msam Mar 22 '13 at 16:35
  • @msam that's right but either you trust the SSL or you don't. Either way, playing with the password won't help and not needed. – SomeWittyUsername Mar 22 '13 at 17:23