0

I'd like to develop a password manager. I am unsure about the safest way to store the data in the cloud.

Credentials (usernames, passwords, login links) will be stored in a MySQL server. I'm planning to store credentials for each site in its own row. This data will be encrypted using the built in methods in Laravel: https://laravel.com/docs/5.5/encryption (AES-256-CBC)

The data needs to be synced between devices, and should not be accessable without decryption from the client (just like a LastPass vault is not decrypt-able by LastPass themselves).

The data needs to be decrypted when it is delivered to the device.

Before I go too far down this path, I'd like to know if someone could give me some feedback of this method, and if using the native encrypt/decrypt methods (https://laravel.com/docs/5.5/encryption) is safe enough compared to e.g. PBKDF2 SHA-256

9
  • 1
    will many users be using this or is this for a single user?
    – schroeder
    Sep 28, 2017 at 13:02
  • 2
    Could you clarify "The data needs to be decrypted when it is delivered to the device." - do you mean that it needs to be decrypted on the device, or that the device needs to be sent decrypted data (hopefully over an encrypted channel). Could be read either way at the moment
    – Matthew
    Sep 28, 2017 at 13:03
  • 2
    It needs to be said: you clearly don't understand how complex developing such a system is. Storing password securely on the cloud is a HARD subject that several large projects have attempted. I would extremely strongly suggest that you do not try to write your own solution. Check what is available first: it is extremely unlikely you will not find a solution to your problem that isn't much better than what you could cook up on your own.
    – Stephane
    Sep 28, 2017 at 13:26
  • Most times people have dared me, I have shown to break their pattern of thinking. I know this is a hard subject. But it doesn't scare me off. Appreciate your feedback though!
    – FooBar
    Sep 28, 2017 at 18:48
  • 1
    PBKDF2 is not an encryption method. please stop your development while you're only slightly behind. there's no need to encrypt on the server/transport if you're under E2E anyway.
    – dandavis
    Sep 28, 2017 at 21:02

3 Answers 3

3

This is not going to work. According to the docs you have to set the key in the php config. That means all users will have the same key and that key would also be stored on the server. That is not what you want.

1
  • Well, you can change the key manually if you want.
    – FooBar
    Sep 28, 2017 at 18:07
2

I understand you want to put something safely stored into a database. You also do not want it to be decryptable by someone getting ahold of the database.

This first and foremost means: You cannot store the key on the same server as the database. But it has other implications. If you are using the inbuilt laravel helper function encrypt() it actually means that the server uses the same password (secret) to encrypt all of the data you feed it. So if you have two customers they will have the same secret key and thus someone who got ahold of the key will be able to decrypt the whole database.

Second: Laravel stored the key typically in the /.env file in laravels root dir on the server. That means: if someone can access the servers files (and even worse if the sql db is on the same server) - the encryption is useless.

What to do? There are multiple ways around it. My preferred option is to use asymetric encryption using OpenPGP. There already is some proper implementation you can use and even a very good reference project wich i encourage you to have a look at: Pass

The data needs to be synced between devices, and should not be accessable without decryption from the client (just like a LastPass vault is not decrypt-able by LastPass themselves).

That is something you can achieve in several ways. But afaik there is no way around storing (at least) the decryption keys on the client (and on the client only) and thus only transfer encrypted from the client to whatever server or "cloud" you will eventually decide on using. The encryption and decryption must be done on the client then.

If you decide on having a webapplication there probably is some way in doing this using JavaScript and storing a secret in the browser but I don't really have a good working example atm.

If you stick to Public/Private keypairs you might as well use the public key to encrypt information from everywhere but only decrypt it on the client (where the private key is stored). Remember though: If some plaintext information is processed on the server it can be caught by someone who as access to it before encryption.

I hope that answers your question at least roughly.

2
  • Interesting with Pas. Do you think it would be integrate-able into a React Native client app? Then the react native app would encrypt and then store it on server. The server would then additionally encrypt the data.
    – FooBar
    Sep 28, 2017 at 18:46
  • Hi Ben! Thanks, I think your answer is great. OpenPGP seems like to way to go, and besides that, I have also found a library for React Native that makes integration easy. I guess keeping the secret keys really secret here is key.
    – FooBar
    Oct 1, 2017 at 13:08
0

Why the need to use laravel's encryption? As Elias says (+1 Elias) if you rtfm the key is stored in a file on the server, nullifying the benefit of encrypting the data.

Laravel's functions are a thin wrapper around the openssl extension in php. There's lots of docs on the internet on how to use it.

It is really important to decide whether passwords will be shared between users. If that will ever be the case, then you need to look at asymmetric encryption (with users public keys on the server).

Ideally you would decrypt at the client. Unless you use a thick client (rather than a browser) with the decryption keys held in a file, then, if your server is compromised it can serve up javascript to read back the decrypted data / keys. To some extent this could be mitigated by packaging and deploying an html5 application to the local filesystem (not loading it from the server) and making [a|s]jax calls out for the data, but I for one would want to test such a configuration extensively.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .