1

Ok so basic overview of the environment I'm envisioning: Webapp w/ db backend storing sensitive data, possibly phi; standard user:pass auth due to unteachable users.

My idea was to encrypt row data in sensitive tables stored in a db using a key that was derived from the user's password (ie the hashed pw using a different algorithm from how the pw is stored in db: eg. store for auth: blowfish(pw), encrypt w/ key=md5(pw) ). That way I could store the encryption key in session (in order to allow authenticated user access to their records w/o reentering pw) without increasing the risk of pw leaking and could destroy w/ session and regenerate on login.

Benefits:

  • It seems to me that an attacker couldn't use the data if they stole it while "at rest", ie the application was shut off or in a backup.

Drawbacks I can already see:

  • If you forget your password, you lose all your data.
  • It becomes impossible to edit db contents manually, everything must be authenticated with the pw used to generate encryption key.
  • Doesn't protect data while a session exists.

What I'd really like to know:

  • Am I missing some fatal flaw in my scheme?
  • Is there a better way to store the encryption key while the session is active?

Clarification:

Ok I think I may have been unclear in my original wording of the question. I meant that I'd store a cryptographically secure hash of the password (likely using blowfish) for the authentication, which means a collision or bruteforce of the password won't be easy (unless someone breaks blowfish, which is always a risk). Simultaneously to authentication (when someone enters their password anyway) I'd hash the password using some other algorithm (probably something like md5 since I don't think it needs to be cryptographically secure at this point) which then would be stored in the session and used to encrypt/decrypt the rows belonging to the user who is authenticated for the duration of the session.

My thoughts wrt to increased attack surface are thus:

  • If an attacker compromises the hash of the password used for auth they can simply log into the application normally and extract the data that way.
  • If an attacker compromises the encryption of the db data then they have everything at that point and there's no point in getting the password. However if they were able to extract the encryption key and for some reason wanted to log into the application they wouldn't benefit from collision attacks on md5 because that's not the hash used to store/authenticate the password. And a collision against one hash is basically guaranteed not to be a collision against another different hashing algorithm.

Possible remediation of below vuln:

  • generate a good pseudo random cryptographic key before any data is stored
  • encrypt cryptographic key w/ password (I don't need to transform the password for this version I don't think)
  • on login decrypt key and store key in session
  • use the key to perform encryption/decryption on rest of the data

why I think this might work is you can't differentiate plaintext from incorrectly decrypted gibberish so the ability to check if your guess was correct is lost, even if you have a list of likely possibilities you can't tell if one worked. Also you get no help brute forcing the encryption key because that's now a proper random value.

  • "store for auth: blowfish(pw), encrypt w/ md5(pw)" ? – domen Sep 10 '14 at 10:34
  • MD5 has been declared cryptographically insecure. en.wikipedia.org/wiki/MD5#Security – RoraΖ Sep 10 '14 at 11:12
  • Yeah I worded that badly, I meant md5 the pw to arrive at a key which is used to encrypt the data. Thus no-where is the md5 stored and thus the strength of the hash isn't actually important, just the fact that it's not the password and repeatable. – Camden Narzt Sep 10 '14 at 14:07
  • No way to recover data with lost passwords is a serious concern. Users tend to forget their passwords all the time. A workaround would be to use a random key for encrypting the data of each user, and store two encrypted versions of that key. One encrypted with the users password and one encrypted with the admins password. That way an admin can decrypt the data and re-encrypt it with a new key when the user loses their password. – Philipp Sep 11 '14 at 9:58
  • Aside from the security issues, who is the user? Imagine 2 drs Adams and Black use your system. In January I see Dr Adams and my phi is secured with Adams password. That means on June appointment with Dr Black, Black cant see my phi without Adams password? Is that what you really want? – emory Sep 11 '14 at 20:53
-1

The biggest flaw I see, is that you are using the password in two different ways, and thereby doubling the attack surface. In your scheme, a weakness discovered in either the encryption method or the hashing algorithm would allow full access to the user's data.

There are three steps you propose:

First: We take the password and hash it using a known good algorithm. This is secure.
Second: We take the password again and hash it using MD5
Third: We take the MD5 hash and use it as an encryption key on some sensitive data

As you can see, the MD5 hash of the password is contained within the encryption of the data. It's not saved directly, but it is implied within the encryption itself. Just like a door lock contains a negative imprint of the key required to open it.

Now, the only way for encryption to be secure is for the key to be way too large to brute force. However, your key is the MD5 hash of the (unknown) password. Now, lets assume I don't care about the password, I just want to get to the data. I don't have to guess the password, or find some weakness with the encryption since you're using MD5 without a salt. I can download a rainbow table of MD5 hashes and use them as decryption key on the data. As soon as the data is decrypted successfully, I know what the MD5 hash of the password was/is. If I am interested in the password, I've already got it from finding the MD5 hash! Further, any user with the same password would receive the same MD5 hash and therefore the same encryption key. I can now decrypt several users sensitive data at once!

It seems to me that full disk encryption would better protect your DB for backups, as the backup would only contain encrypted information. However, this wouldn't prevent an active attack, while the application is running.

  • I don't know if it does increase the risk though, presumably if there's a flaw in the encryption the sensitive data is already leaked, and therefore there's no point to protecting the password anymore, as there's nothing more to gain. – Camden Narzt Sep 10 '14 at 14:23
  • Ah no, sorry. I meant the encryption scheme you will use on the password. In your original post, you suggest using MD5 to arrive at the encryption key to then encrypt the data. Since MD5 is insecure, I can generate the same encryption key that you used to encrypt the data by leveraging a collision attack on MD5, without knowing the original password. – Chris Murray Sep 10 '14 at 14:35
  • except to my knowledge you need a hash to perform a collision generation. Since the hash is used as the encryption key it's not stored (except ephemerally during an active session, say in ram) and thus you'd have to somehow reverse the encryption to get the key at which point the collision gains you nothing since you already have the sensitive data decrypted. – Camden Narzt Sep 10 '14 at 16:12
  • On the contrary, you have saved it, as the key to the encrypted files. The encrypted files themself provide a way to verify I have the correct key. Essentially what you are doing is storing the password as a MD5 hash without salt. Normally, I'd have to brute force your encryption key, which is close to impossible. However, in your case, I only have to brute force the MD5 hash (which is not impossible) and bam, I have your encryption key that I can then use to decrypt the data. All without breaking the encryption on the files, or knowing the password. – Chris Murray Sep 10 '14 at 16:22
  • So if you use decrypting the data as the check for your brute force of the md5 then you are brute forcing the encryption key anyway, as the md5 hash is used as the key. Is the issue that md5 or the like limit the character space? I'm not sure what is gained knowing that the key was generated from a hash, but I'd like to understand. – Camden Narzt Sep 10 '14 at 17:40
0

The only real security issue I see with your approach is that you only seem to talk about encrypting the data -- you do no check that the encrypted data has not been tampered with. It would possible to modify encrypted data (where you just took a message, applied AES-CBC or AES-CTR mode to the data), where you can guess the form of the plaintext and alter the value (by XORing as appropriate to the block cipher mode to change the corresponding XOR of the plaintext data). The way to protect against this is to use authenticated encryption modes that combine encryption with a message authentication code (roughly a hash that you can only construct if you know the secret key).

I do see many usability issues from your approach. First, you lose most of the benefit of using a big database to store information about lots of users. You can't add or update or modify encrypted information for a user if that user is not logged in (e.g., as is couldn't use this for a messaging system, or for a system that automatically imports information from an external source). You can't build any indexes, or fast searches, or agreggations, or joins inside your RDBMS that act on data in an encrypted row. Your database query planner can't plan for the distribution of your encrypted data to execute the right plan. Data can't be shared amongst users who should be able to access the same information without keeping redundant copies, which goes against the basic rules of database design and will leave you with inconsistent data (as you can only update the information for the current user).

As you mentioned, there's no way to deal with a user forgetting their password without wiping out all their data. You would need to modify this so this feature is present, as real users will need their passwords reset. (You can do some sort of system where you store every users key in an encrypted fashion with a strong passphrase protected key).

Finally, this doesn't buy you much extra security. Any one who gets administrator access on those systems could get access to the protected data if they were a little patient and just waited for the user to login. They merely log the incoming network requests and capture the user's passwords (at which point they can decrypt the data, either through the system, or from a database dump). It does not seem significantly safer than having a well developed application sitting on an encrypted hard drive (with encrypted backups), where strict user controls and logging are done at all steps.

  • I agree that this is definitely not sufficient as a security scheme, nor is it intended to ever be put into use, it was simply my curiosity as to what flaws I might have overlooked thinking up my own system. Basically this is harmless practice instead of building something and finding out it's broken the hard way. – Camden Narzt Sep 10 '14 at 21:42

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.