amuck-landowner

Passwords and Storage!

MartinD

Retired Staff
Verified Provider
Retired Staff
So, you've written a little application that requires a login and you authenticate against a record in a DB (in whatever fashion you have chosen). All is hunky dory.

You now want to use this application to store other passwords - to have a list of usernames, passwords, ips etc for devices/logins. Obviously you can't store these in plain text but they need to be some-how encrypted so that only an authenticated user can get in. You also need to be able to view/recover these passwords for use i.e. "click to view" and they show up. Salting against the original auth password wont work then for obvious reasons.

How would you do it?
 
Last edited by a moderator:

drmike

100% Tier-1 Gogent
Well why disclose the password ever again? 

If they forget such, then time to generate a new password. 

I've never understood the show me the password... I should know the password and in case I got sloppy or misplaced it, getting or setting it fresh is fine.

I guess I'm paranoid like that.  Hate seeing PWs, hate such in email, etc.
 

MartinD

Retired Staff
Verified Provider
Retired Staff
It's about having a place to store passwords for other devices/systems that can be retrieved - like a password manager.
 

AThomasHowe

New Member
Have a master password that's used to unencrypt the data that is a hashed and salted password? One per user.
 
Last edited by a moderator:

MartinD

Retired Staff
Verified Provider
Retired Staff
That would mean storing the same passwords/credentials multiple times, once for each user?
 

AThomasHowe

New Member
That would mean storing the same passwords/credentials multiple times, once for each user?
Why couldn't you encrypt a JSON file or something? Then it'd just be one encrypted file per user.

Assuming it's a simple username/email & password login combo (or something like login codes/tickets/etc).

edit: or BSON for Binary data.
 
Last edited by a moderator:

splitice

Just a little bit crazy...
Verified Provider
If I am getting you right you want to be able to decrypt records of another table based off private data in such a way that it is not possible to decrypt this data without first being authenticated (in such a way that the server does not have all the details required to decrypt on its own).

Terms Invented:

  • detail - the table of things you want to protect
  • secret - the text of the the thing you want to protect (in details table)

In this setup:

  • It is not possible to access the secret plain text with just the information on the server (stored)
    Protected against malicious admin
  • Protected against breach by hacker
[*]It is not possible to obtain the secret plain text with just the user supplied password (of course)
[*]The security of the crypt key (e.g user password) is not weakened by repeated use as an encryption key against possibly known secrets (attack by insertion or guessing of known secrets to obtain access to other secrets by obtaining crypt key or weakening encryption)

I would recommend (I will use):

  • store user_password (hash): password + salt (repeat as appropriate) 
  • For each encrypted "detail":
    key: Key encrypted with plain text (or derivative of) user_password
  • secret: Secret text stored encypted with value
It is not possible to decrypt the "secret" detail without first having access to detail "key". detail "key" requires the plain text password (or a derivative of) to decrypt. The plain text password is not stored on the server at all and needs to be supplied by the user.

The encryption that could be used can be any stream cipher, use a randomly generated key (then stored with encryption with user_password) for detail "key".

Note: Just something I forgot, you may want to transform user_password before using it as a encryption key against detail "key":

  1. Encrypt it with a server key, this adds another layer of security in case of breach (file can be deleted)
  2. Passwords are generally ASCII characters of a high compression ratio and atleast somewhat predictable, also being limited to ASCII means smaller keyspace (and one that can be ordered based on natural language rules for large percentage of password)

Sorry If I am not as good at explaining Cryptography, its been a while since I did that unit.
 
Last edited by a moderator:

splitice

Just a little bit crazy...
Verified Provider
Just for additional information, a more formal definition.

Given:

Decrypt(CryptText, CryptKey) := PlainText
Encrypt(PlainText, CryptKey) := CryptText

UserPasswordText := User Supplied Password
DetailKeyText := Randomly Generated Key for storing new Secrets
Store:
Code:
SecretCrypt = Encrypt(SecretText, Decrypt(DetailKeyCrypt, UserPasswordText))
DetailKeyCrypt = Encrypt(DetailKeyText, UserPasswordText)
UserPassword = OneWayHash(UserPasswordText)
 Then to display:

Code:
SecretText = Decrypt(SecretCrypt, Decrypt(DetailKey, UserPasswordText))
 
Last edited by a moderator:

MartinD

Retired Staff
Verified Provider
Retired Staff
@splitice - thanks very much for that. That's along the same kind of lines I've been looking however yours is more in-depth and detailed. Unfortunately, it has the same problem that I came up against;

1) What if an admin/authorised user forgets their password (to the password manager) and it is changed - it would be impossible to recover the stored passwords;

2) A single 'key/password' (2nd auth) to decrypt and recover the stored passwords (in the password manager) is a big security issue (among others, I know). Ideally, each person with access needs to have their own passwords with no data/passwords/keys shared with other users.

p.s. - I've been at this on and off for the past ~6 months. Haven't yet figured out a safe way to do it!
 

splitice

Just a little bit crazy...
Verified Provider
1) can be solved through the use of additional authentication secrets and another layer (you can do this without the extra). For example, secret questions:

UserKeyText = [RandomText]
Code:
SecretCrypt = Encrypt(SecretText, Decrypt(DetailKeyCrypt, UserPasswordText))
DetailKeyCrypt = EncryptManyKey(DetailKeyText, [UserPasswordText, UserSecretAnswer1Text ...])
UserPassword = OneWayHash(UserPasswordText)
UserSecretAnswer1Crypt = OneWayHash(UserSecretAnswer1Text)
....
EncryptManyKey is n-key encryption. This can implemented with a sub-key is encrypted with each supplied key, this sub key is the key needed to decrypt the actual text for that value. This is how LUKS and probably filesystem encryption tools works FYI. I suspect there may be specific encryption libraries geared to this use case, although I have not investigated it.
2)

I am not sure I understand, but user sharing is just a matter of either sharing the same DetailKeyText (bad) or adding another key for authorizing access (for which the users key must be added for access - another EncryptManyKey)
 
Last edited by a moderator:

perennate

New Member
Verified Provider
splitice's approach seems solid; you might as well use an existing system like gpg: Encrypt = gpg encrypt, Decrypt = gpg decrypt, DetailKeyText/DetailKeyCrypt = plaintext/passphrase-protected PGP private key (and when encrypting, public key is used).

Then let user have backup detailkeytext or something?
 
Last edited by a moderator:

MartinD

Retired Staff
Verified Provider
Retired Staff
Think I may have to fiddle around and make some PoC examples to see just how it works.
 
Top
amuck-landowner