What's a good way to handle encrypted data that requires a password to access?

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
I'm working on redesigning my password manager as it was quickly thrown together a while back with intention of making it better. Right now the password to get in *IS* the encryption key, which is not exactly ideal. So now I'm making it better.

So I will make it so there are one or multiple keys that are proper 256 bit binary random strings. Will be using AES-256. (open to other suggestions did not really pick that one for any particular reason, just had to pick something)

Now the keys obviously have to be encrypted or otherwise stored in a secure fashion. I'm thinking of just encrypting them with my password, and when I change my password then it just needs to reencrypt the keys. Right now it would need to reencrypt all the passwords. But this kinda brings me back to square one, if someone gets ahold of the database they just need to brute force the password to get the key and then use it to get the data.

How is this normally done? Ex: how are keys secured so that only authenticated users can use them?

This is a web based application using php. It would be running on my local network.
 

beginner99

Diamond Member
Jun 2, 2009
5,210
1,580
136
It's common practice that the passphrase is used to encrypt the actually encryption key which you generate randomly. And I intentionally say passphrase because a short 8-char password will make it trivial to "hack" the key.
 

cytg111

Lifer
Mar 17, 2008
23,221
12,861
136
password manager... local network... php...

Are you doing your self any favors here? :).
 

beginner99

Diamond Member
Jun 2, 2009
5,210
1,580
136
password manager... local network... php...

Are you doing your self any favors here? :).

Yeah the number one rule with cryptography and IT Security is: Don't roll your own. That will lead to disaster and if it doesn't you haven't been attacked yet.
 

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
So general consensus seems to be to store the keys locally? What happens if something happens to that machine? The idea behind my password manager is that it can be accessed from any machine, any device, as long as it has access to that server. Don't want to deal with browser extensions either as that means it's specific to that browser/machine and has to be setup on each one.

How do things like trucrypt and PGP do it? As long as you have the encrypted file, all you need is the password and it does not rely on anything on the machine, as you can put an encrypted file on a USB stick and open it on another machine.

Yeah the number one rule with cryptography and IT Security is: Don't roll your own. That will lead to disaster and if it doesn't you haven't been attacked yet.

I always hated this philosophy. If everyone followed this everything would be clear text because nobody would ever bother implementing encryption into anything. At some point, every piece of software you see that has encryption had to be coded by someone that had to implement encryption into it. Any encryption is better than no encryption. Of course you should use well trusted libraries and algorithms, but even then, there is nothing wrong with trying out new ones, though that is not what I'll be doing. Using OpenSSL's implementation of AES256. Spreading knowledge on how to impliment it properly should be encouraged not discouraged.

When I switched to Linux I also wanted to get away from desktop based password managers like PINs as I wanted something that does not rely on having a specific software/config locally, and could not find much in terms of php scripts that I can just setup on a web server, so that's why I wrote my own. It's a fairly simple database system where I can search/add/edit records, except the fields are encrypted/decrypted on the fly. That way if someone was to break into my house and steal the server, or manage to compromise it remotely, it's encrypted. It would at least buy me time to go and change all my passwords everywhere.
 

beginner99

Diamond Member
Jun 2, 2009
5,210
1,580
136
I always hated this philosophy. If everyone followed this everything would be clear text because nobody would ever bother implementing encryption into anything.

Hating it doesn't make it wrong. And not you completely missed the point. The reason is, it's hard and if you use an existing open-source solution that has been tested and looked at by many eyes, then a severe bug is much less likely. But even then there is no guarantee. It's simply arrogant to believe you can do at least as good as 100 security experts.

AES256 can be used wrongly very easily and putting your home brew password manager on a web server. good luck. At that point your probably safer using 2-3 complex password everywhere and be done with it. (+ 2-factor)
 

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
H
AES256 can be used wrongly very easily and putting your home brew password manager on a web server. good luck. At that point your probably safer using 2-3 complex password everywhere and be done with it. (+ 2-factor)

So what is a way to do it properly? That's what I'm asking. There's got to be a way, or none of the existing software that uses it would be secure. Why does the tech community feel it's best to hide this information and discourage it? It's not just here I see that, but even when trying to google stuff, forums in general etc. It's very hard to find information on proper practices with crypto because everyone is so secretive about it and just tells people not to bother.

I used to use a password manager called PINs. There are many similar ones but they are desktop apps and I don't want to be tied to a specific platform or having to install anything on each machine which is why I'm coding a web based one. How do those store the key? It is a database, usually a file, that can be opened from any machine that has the software installed.

The key is in the file somehow, but obviously has to be stored in a way that is secure. So how is this done? Is the key just encrypted by the another key derived from the user's password? Or is there more to it? That's kind of what I'm leaning towards. When I login, once authentication is good, a hash (maybe using SHA-256?) is created using the user's password (which is going to need to be long - ex: an actual pass phrase not just a small password), and that hash becomes the key to encrypt the main key(s). Does that sound like a good plan or is there a better way?
 

sdifox

No Lifer
Sep 30, 2005
95,030
15,141
126
So what is a way to do it properly? That's what I'm asking. There's got to be a way, or none of the existing software that uses it would be secure. Why does the tech community feel it's best to hide this information and discourage it? It's not just here I see that, but even when trying to google stuff, forums in general etc. It's very hard to find information on proper practices with crypto because everyone is so secretive about it and just tells people not to bother.

I used to use a password manager called PINs. There are many similar ones but they are desktop apps and I don't want to be tied to a specific platform or having to install anything on each machine which is why I'm coding a web based one. How do those store the key? It is a database, usually a file, that can be opened from any machine that has the software installed.

The key is in the file somehow, but obviously has to be stored in a way that is secure. So how is this done? Is the key just encrypted by the another key derived from the user's password? Or is there more to it? That's kind of what I'm leaning towards. When I login, once authentication is good, a hash (maybe using SHA-256?) is created using the user's password (which is going to need to be long - ex: an actual pass phrase not just a small password), and that hash becomes the key to encrypt the main key(s). Does that sound like a good plan or is there a better way?


just read the stuff from OWASP I linked


https://www.owasp.org/index.php/Category:OWASP_Project#tab=Project_Inventory
 

sourceninja

Diamond Member
Mar 8, 2005
8,805
65
91
OWASP provides top 10 lists, tools, and other guidelines for information security standards. It's pretty much a bible. After that I'd start reading NIST frameworks and guidelines.
 

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
Yeah it does appear to have lot of useful stuff about general security I'd have to go through some day, but that link does not really answer my question.

Ended up just going with my original plan. I create a password derived hash, that is different than the hash stored in the DB, and that hash is used to encrypt the actual key used to encrypt the data. To avoid having to enter the password each time I want to decrypt a password, the password derived hash is itself encrypted in the session table (new session entry created at each login), and the key to THAT key is stored in the user's cookie which is set to http only. New random key for each login.

When changing the password to access the system, then a new password derived key is created and all the keys are re-encrypted with it, and all sessions are deleted. This key is never stored, it's just consistently generated based on the user inputted password, or the cookie.

Ideally I want to use a strong password as the password in itself is basically a key to decrypt everything. Since the key has to be consistent after each login I can't really use a random salt so I just use the one that is used to hash the login password and append extra consistent data.

I'm fairly confident with this method but I'm open to suggestions if there's a flaw in it. I made all keys, hashes etc use 256 bits, not sure if that's good or if I can go higher, or if it matters to go higher. AES-256 is used for the encryption, and right now I'm using MD5 for general hashing as needed because it's built in to php, but I'll be changing that to bcrypt. I found a library, just need to set it up.
 

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
Huh? Never said that, but either way this is going to be running on a local server so probably does not matter anyway. I'll probably setup a self signed cert for good measure though. If you're talking about the http only flag, it stops cookies from being accessible through javascript. So a malicious web site would not be able to pull the database by using my browser's cookie. Ex: if your logged in to a site and the cookie is not httponly, you could land on a malicious site that then accesses that secured site as you by using your cookie. By setting all cookies to http only it prevents that. IMO that should be default, I don't get why it's not.
 

sdifox

No Lifer
Sep 30, 2005
95,030
15,141
126
Huh? Never said that, but either way this is going to be running on a local server so probably does not matter anyway. I'll probably setup a self signed cert for good measure though. If you're talking about the http only flag, it stops cookies from being accessible through javascript. So a malicious web site would not be able to pull the database by using my browser's cookie. Ex: if your logged in to a site and the cookie is not httponly, you could land on a malicious site that then accesses that secured site as you by using your cookie. By setting all cookies to http only it prevents that. IMO that should be default, I don't get why it's not.

or just not allow any sort of http access to your data.

implement this

https://www.nitrokey.com/
 
Last edited:

mxnerd

Diamond Member
Jul 6, 2007
6,799
1,101
126
Why only MD5 when you are so paranoid about the security when SHA256 is also built-in in PHP?
 

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
md5 is just a placeholder. Going to be changing it to bcrypt then tweaking it to use an acceptable difficulty factor. There's a couple places within the program where stuff needs to be hashed, such as verifying session cookies, and logging in.

Not sure how that USB thing would help, do I put that on the server and it acts as a secure store to put the database on? It's a VM, so I'd have to mess around with USB pass thru and stuff which I've never really gotten to work reliably. Could just do full disk encryption but chances are if the server gets compromised it's running. So it's best to just secure stuff right within the mysql db. I just base64 encode it after encryption and put it in text fields.
 

sdifox

No Lifer
Sep 30, 2005
95,030
15,141
126
md5 is just a placeholder. Going to be changing it to bcrypt then tweaking it to use an acceptable difficulty factor. There's a couple places within the program where stuff needs to be hashed, such as verifying session cookies, and logging in.

Not sure how that USB thing would help, do I put that on the server and it acts as a secure store to put the database on? It's a VM, so I'd have to mess around with USB pass thru and stuff which I've never really gotten to work reliably. Could just do full disk encryption but chances are if the server gets compromised it's running. So it's best to just secure stuff right within the mysql db. I just base64 encode it after encryption and put it in text fields.

no as in if the key is not present you cannot decryt

https://docs.vmware.com/en/VMware-W...UID-07883F0A-E7B5-4CBA-837D-0BA986E8B900.html

of course you still do password and 2fa on top of it. But the point is to have different vectors for each elements.
 
Last edited:

Red Squirrel

No Lifer
May 24, 2003
67,403
12,142
126
www.anyf.ca
Suppose wine and coding stuff related to cryptography do not mix, but here's what I ended up doing as none of that stuff answered my question (though it does look like some good stuff to read for general security knowledge)

Anyway so here's what I ended up going with:

- When you login, your password goes through a fairly standard hash routine (using bcrypt now) to verify against DB hash. If it matches your login is successful, if not, well it fails. This part is fairly standard and basic and simply is the first step to authenticating to the system as a user.

- Now for the decryption part, the password is also hashed through a different function. In this case I needed a consistent salt that I could generate and store myself, so I went with SHA-512 + a salt that was generated when the user originally set the password. The idea here is that given a password, I will always get the same hash which I will call the password key here. Bcrypt did not work as it handles the salt internally so will always generate a random hash with same data.

This password key is the encryption key that is used to encrypt the key that encrypts the actual stored data entries. This password key is not stored as-is anywhere, and can only be generated by logging in.

- Now I don't want to type my password every single page load obviously, so this is when the session management comes in. Upon a successful login, and after generating the password key, a randomly generated hash (the fact that it's a hash does not really matter here, a hashing function is simply used so that it's database friendly data that comes out) is created, which is the session hash for that specific login session. This session hash is then hashed again. This is used as a key to encrypt the password key previously generated based off the password. This key, is then stored in the user's cookie, and not stored anywhere else.

- The session hash and encrypted data(the password key) is stored in the session entry

- Now that the cookie is set, the cookie can be verified against the DB to make sure the hash is valid to authenticate to the system, but also the cookie hash is the key to decrypt the password key, which can then decrypt the data

Now here's the fun part. When the user changes their password several things happen:

- new bcrypt hash generated using the bcrypt function

- New salt is generated, for good measure this salt is used with brcrypt even though bcrypt uses it's own salt. Figure it does not hurt. This salt is for the pasword key otherwise it would not really be needed.

- All the keys now need to be decrypted with the old password key (which will be available as changing password requires to specify old password) and then re-encrypted with new password key (which is derived from the newly entered password and salt).

- All existing login sessions are also cleared at this point. Any stored cookies on any machines are also useless even if I did not clear sessions as it would not be able to decrypt the keys anymore. Not clearing the session table would allow an old cookie to still be able to login, but then it would not decrypt the data.

Think I about covered it. Might be forgetting some details.

Hope all this makes sense I had like 2 glasses of wine. lol.

Basically TLDR: The keys used to encrypt the password data is encrypted by a key that can only be obtained by knowing the login password, or having a cookie that was previously set by knowing the login password. This way it does not need to actually be stored anywhere.

One weakness is that the database being compromised and a cookie being compromised could basically be used to decrypt the data. But someone that has access to both is probably already deep enough in my network that I have more serious things to worry about, and could easily just login by controlling my browser anyway. To slightly mitigate that, login sessions are going to be kept short. Once a session expired the cookie associated with that session is useless.