In my application I have to do repeated calls to webservices which require authentification. The users do not want to repeatedly enter authentification information (username and password).
Is there an secure way to store the password at least for the length of the session the application is running, so the user has to enter the data only once?
At the moment I hold the password in memory and encrypt it after entering and decrypt it when it is used for the service call. But I feel somewhat uncomfortable with it.
Is this a recommend way to handle that kind of data?
What about storing a password in a database to use it in multiple sessions?
Is there an recommend way of handling that? I heard of bcrypt and pbkdf2. But they are just for hashing purposes and to compare an entered password against, not to use the "decrypted" password again.
Or would it be a better approach to use an external password cache, like keepass (or whatever there can be used).
For in-memory storage, use SecureString class or NetworkCredentials, that uses SecureString internally.
For persistent storage, encrypt the password using Data Protection API. It will encrypt it with the key that is only accessible to current windows user on this computer.
Related
There are a bunch of discussions on here regarding encrypting and decrypting strings but they are all quite a few years old and a lot has changed over the past few years.
For user passwords I use hashing so a password cannot be decrypted.
However, I have a few services I connect to on the back end and need to encrypt a password in a DB so it can be decrypted to run at a later time.
In the past I've used DPAPI. Is that still the "best" way to store this information in a DB?
The best way is "don't do it". If you keep credentials, someone will eventually steal them.
Most back ends have some way of granting an authorization token of some sort that you can use, so you don't need to keep sending a login/password.
There are "new-er" ways of storing credentials like password vaults, secure storage and various types of hardware-based secure storage, but if your program can extract them as plaintext, an attacker can too.
Check into Kerberos Authentication It uses tickets and encrypted mutual authentication to let devices trust each other, without needing to exchange or store plaintext credentials.
If you're on Windows, look into "Integrated Authentication" which usually uses Kerberos.
I'm working on a couple of projects that need to store user credentials for third-party applications, such as Paypal, Facebook developer creds etc. I've read a few books about different kinds of coding, including ASP.NET, WPF, jQuery, and all have nice examples on how to access the preceding services with own secrets, and also all of them use the exact phrase "in a real project you would store these in an encrypted file". None, however, give an example how to do so.
I have little (read: none) experience in encryption, but based on my understanding, I would need to encrypt a username and a password using some sort of key (salt?) and save them in a file. I would also want to be able to use these credentials on my apps so I would need to store the key (salt?) in my code.
Now my question is: How is it safer to store the decryption key, which is still plain text, in the program code, than the actual credentials?
Wouldn't the malicious user be able to decrypt my password-file as soon as he gets the key?
--EDIT--
I really mean my own credentials I need to store to log in to third party applications, not credentials of my users. For example I need to identify my self and/or my app to Google, so that users can log in to my app using their own Google account.
--EDIT 2--
To clarify, this is what I'm talking about. This screenshot is from asp.net PayPal tutorial:
Any quick pointers on good practises here?
You misunderstood the part about storing encrypted password* + salt: this is done when your system needs to validate someone else's credentials. In this situation storing password hash and the salt is more secure than storing the credentials, encrypted or not, because an attacker would have no way of getting the password back, even if he manages to get his hands on both the hash and the salt.
Storing decryption key in plain text is never a good option, because an attacker would get your users' passwords as soon as he gets access to the key.
There is no good solution to persisting your own credentials, encrypted or not. Your component that talks to 3-rd party services should use developer APIs from these providers. For example, PayPal provides two sets of APIs which you can use to access your account without having to store your password.
If you need to store a small amount of secret information in an encrypted form, use registry APIs to store the data in a key known to your application, and accessible from the user running your server-side component. This secret would be safe, as long as hackers do not hack the password for the account under which your service is running.
* Technically, password is not encrypted, it's hashed, i.e. there is no reliable way to turn the result of conversion back to the original value.
Your suspicions are correct. If the user has access to the key they can just go and decrypt the username and passwords themselves.
The two options you have are
Make it difficult enough to get the password that the reword of getting the password is not worth the effort to find it. This approach is done via things like Code Obfuscateors, I would not recommend this to someone starting out. Its not easy to get it right and it only takes one person who things it is "worth the effort" for it to break.
Don't give the user the information ever. Instead of storing the usernames and passwords in the program have your program call out to a server you own, then that server is what makes the request using the credentials. This approach is the more reliable one and is "unbreakable" (as long as your server is secure) but costs more because you now need to keep a server up and running that can handle the load of your entire userbase.
For user passwords, we should always hash and salt them and then store the hash and salt in the DB. But what's the best practice for storing passwords that need to be eventually be in plain text? I don't feel comfortable storing a plain text password in SQL, but I have to send the password to a library so it can access something.
My thinking was that I could store an encrypted password on the database server and then decrypt on the web server. If both are compromised, I'm screwed. But if just one if compromised, the encryption gives me enough time to change the password.
What do you all think?
To be on a safer side, just hash the password and save, then you can compare user password input with the hash code in your database when you need to authenticate.
If you really need to get plain-text form of password ( which is really not good idea ) you can use symmetric encryption for security user passwords. But you must figure out how to keep private key in secure. I mean you need a private key in your code in order to decrypt data. Also all of your developers can access private key which means they can access plain-text too.
Also I suggest you to read this article. It's comparing hashing and encrypting user password. http://www.darkreading.com/safely-storing-user-passwords-hashing-vs-encrypting/a/d-id/1269374
Microsoft provide an API for this use case as part of the Crypto API. It's not particularly easy to work with, but provides much better security than storing keys in text files, or in the database.
It's fair to assume that if an attacker can get onto your database server, they have access to every system in your environment; and even if you think you have "time to change the password", how would you know your system has been compromised? Most attacks aren't noticed until much, much later...
We are currently developing a web application in .Net which will also have Android, iPhone and Windows Mobile 8 apps to occupancy it. All of these applications need to have a unified login system. Our site and web services will be using SSL but obviously we want to do all we can to make sure user passwords stay safe. As such we are looking for a common password hashing function that can be used throughout the platforms outlined above.
Currently the only common one we have found is SAH256 however I would like to use something a little stronger. C# has the Rfc2898DeriveBytes class which I would like to use (and can be used in the website and Win8 Mobile) but are there any implementations of this for Android/Java and iOS/Objective C? If this can’t be used what would be our next best option?
The password hashing function should be used on your back-end when storing the user's password and comparing during a login attempt.
Login scenerio:
User sends password over SSL via one of the versions of your app.
The back-end server hashes the password that was sent from the user, retreives the stored hash from the data store, compares the hash of the password sent with the stored hash.
Hashes match, user is allowed access, otherwise access is denied.
The SSL encryption prevents exposure of the password during transmission from the client, storing passwords as hashes prevents exposure of user passwords if your database is breached.
Using this scenerio, since the hashing is all done at the back-end server, only one implementation of the hash algorithm is required.
PBKDF2 is not something that fits well in your situation. It is mainly intended to prevent attacks when the attacker already has your data (ie. an encrypted file). It does this by eating up CPU to force a delay during brute-forcing. Because you're performing auth server-side, you can easily save some CPU and just wait a second or two to send an response to the client if they get the password wrong. Just use a salted hash (like HMAC), and you'll be fine.
If you're using SSL, then your passwords are secure. The only way you can do any better is to implement full public-key crypto, which can prevent MITM attacks. SSL even has this built in.
Sending password hashes over a network is not really more secure than sending passwords. Yes, the password text is hidden from attackers, but they've still got the hash and if they have that, they don't need the password. In the case of SSL, your plain text is also protected.
While I've never used it personally, bcrypt appears to have all the implementations you are looking for.
http://en.wikipedia.org/wiki/Bcrypt#See_also
Hope that helps.
I need to store my users' name/password somewhere (preferably the Registry) so my .Net application can use them to log in to some remote service on behalf of the user. I know it's possible to store values in the registry as "secrets", which means their encrypted using the Windows domain user token or something. In other words, I don't want to have to deal with the encryption myself.
To clarify: I can't store hashes of the password or salt them or anything. These credentials are for a 3rd party system and the only way for me to be able to login to this system on behalf of my users is to somehow keep their credentials and be able to restore them.
So anyway, I remember vaguely there's such a place in the registry, but the details are murky. And I need to do it in C# (though if it's simple registry access it shouldn't matter).
Edit: One more thing, it should persist between Windows user sessions (IOW it doesn't help me if the password in unreadable after the user logs off and on).
You're probably thinking of the Data Protection API. Search MSDN or read some blogs and see if that'll work for you.
You can try using System.Security.Cryptography.ProtectedData, which can encrypt them using a per user key. http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx.
It's not completely secure, since code running as the user could decrypt the data.
Keep in mind that you're not really securely storing anything if you can automatically (without user input) retrieve the password. Using RSA, symmetric, or other encryption doesn't make a difference so long as you store the decoding key within your application. Once anyone gets the key, the secret's out.
However, the Data Protection API mentioned above should protect passwords from other users on the same machine. (It sounds like DPAPI uses your login credentials for encryption.)
For a few more options, check out the msdn page for Threat Mitigation.
You should never store credentials as plaintext. Use a symmetric key cipher. Take the password out at runtime. See the MSDN reference on Cryptography functions.