1

I've already asked that question at stackoverflow but i was informed it is a bit too broad and relies more in here instead. So let me just copy and paste what i asked there:

I have a security related dilemma which i'm unable to figure out by myself from my knowledge about web applications security.

Let's say i want to create a service where user can store and VIEW in plain text its passwords for multiple services. In such case we have few things to consider: basic security measures by encrypting stored passwords with hash, how to protect passwords in case if they would have been stolen from database by, for example, dumping the database by attacker.

This means passwords would need to be stored encrypted but being possible to display to a user in plain text. Standard way to store passwords for authentication is to hash them for example with bcrypt or other method with salt added to it and such encryption doesn't let you to decrypt passwords easily.

Is what i want even possible to achieve? Or is there any other approach i should take instead of hashing but still secure to store multiple passwords to multiple services by a single user?

I will just add to it that let's assume single password or set of passwords is a blog post to view in a plain text only by author of such post and under specific circumstances by admin and moderator.

Technology itself probably is not the most important thing here but i'm going to make this application using php and laravel framework.

To store and to view is one thing, other thing is how to secure such application from various kinds of encrypted posts hijacks, database dumps and similar attacks?

  • 2
    Start with, "Why?". Are you trying to build something like a password manager, or are these passwords for authenticating with a third-party service? If it's a password manager, you'll have no choice but to use reversible encryption. If it's to access other services on the user's behalf, there may be options to store a short-lived token for that service, instead of a password. Storing the user's password is never ideal for third-party service authentication - but there are times when the third-party just gives you no other choice. – nbering Sep 29 '18 at 15:26
  • Yes, sort of password manager, more like private safe/locker where user can store its passwords to access them in form of plain text. This will not be for authentication like oauth or similar services. – spectatorx Sep 29 '18 at 15:30
  • 1
    In that case, I don't want to discourage you, but there's an awful lot of products out there that already perform this function. Consider if something already meets your needs, and whether you actually need to build this yourself. If you decide you really need to build something yourself, OWASP has some excellent guidance for building access control systems, and there are some great libraries out there for working with encrypted columns in databases. Choose something that works well for your language of choice. – nbering Sep 29 '18 at 15:34
  • If you want a crypto-heavy backend so you don't have to deal as much with Cryptography - consider using Hashicorp Vault. It's more of an API than a database, but it's quite robust. It's non-trivial to work with, though. It's basically built by CS geeks for security professionals. The access control configuration is pretty abstract. – nbering Sep 29 '18 at 15:37
1

In general:

  • A one-way hash is non-reversible (hence the term one-way)
  • Encryption is reversible (provided you have the decryption key)

For regular authentication, we use store password-hashes in the database. Then we hash a user-entered password and compare that to the hash in the database. This way we can authenticate a user without ever storing the password. If the user chose a 'strong' password, it'll be impossible (or at least immensely difficult) to obtained the users clear-text password even if the entire system was compromised.

However, what you're asking for is to retrieve the cleartext password -- which isn't required under most circumstances. The user already knows their password (otherwise they wouldn't have been able to log on) -- and if the user forgot, we'd generally reset the password, by first authenticating an email address or phone number first, and then re-writing the hash for the new password.

If instead you're asking to store 'data' on the account that isn't accessible to anyone without the password -- then the general solution most password-managers utilize is by encrypting the data with key derived from the user password (because user passwords can be quite weak). The data can be a encrypted blob, that would be decrypted on the user-end using their derived key.

The drawback (sort of) is that if the user loses their password, there is no recovering this data, but for most password managers this is actually a 'feature' because nobody wants this data stored in the clear on any server.

Again, the solution would be quite useless if the user chose 'Password1234' as their master password, but there are other solutions for that.

  • Forcing strong password on service user is a must in this case. Encryption method you mentioned. utilizing user's password as encryption key sounds good but what if user will decide to change password or i will be forced to reset passwords of all users after breach? – spectatorx Oct 1 '18 at 12:42
  • Good point. The way this is resolved for full disk encryption utilities is by encrypting all the ‘data’ with a secure key, and then using the user provided password to encrypt that key. To decrypt, the user password ( or derived key from password) will be used as a key to derive the data key, and then we use the data key to decrypt the data. This way a password change merely requires you to re-encrypt the data key. The user password (or derived key from it ) is called the key encrypting key. – keithRozario Oct 2 '18 at 13:09
0

A secure set-up

I recommend encrypting users' passwords using a derived key from the user's normal password. I would use bcrypt for storing their password, PBKDF2 for generating a key and AES for encryption. A set-up could be:

  • Store the normal password of the user with bcrypt;
  • When the user logs in successfully, use PBKDF2 in Javascript to generate the user's derived key in the browser;
  • Send the user their (AES) encrypted blob;
  • Decrypt the blob in Javascript, in the memory of the browser;
  • When the user is done doing their thing, have them send back an (AES) encrypted blob.

This way the server will never see a user's password or their encryption key. Breaking the encryption would mean brute-forcing the user's password, in which case you can access the user's data anyway.

Other ideas

I would like to add that it might not be necessary for users to actually view their passwords. For example, most password managers don't display passwords but copy them to the clipboard directly. You could have their decrypted blob in memory and have something like a [copy] button that copies the password to their clipboard. This would not just be more secure, but also more convenient for your users.

0

From my understanding you're trying to build a password manager/vault. You can't use hashing for data storage in that case.

You'd definitely be better off using one already out there as it's very easy to get wrong.

You'd have to use symmetric key crypto to encrypt the passwords, and derive the key from a user's password.

I wouldn't recommend you do this yourself really, there's a lot of ways to go wrong. I.e. weak keys/crypto function, storing/transmitting the secret key incorrectly, data integrity, database breaches etc...

As has been mentioned refer to OWASP for app security guidelines, I believe there's a cheat sheet on there to help developers build better software too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.