I know there have been a few questions about this already, but I just wanted to know if anyone can take a look at my design plans to see if there are any gaping security holes. I am in the process of making a web application which securely stores sensitive information that can then be retrieved by staff members who have access to it.

I have two servers - a main server and a decryption server. The main server stores the encrypted data, authenticates the users, outputs the HTML, etc. The decryption server only stores a partial private key and does the decrypting when the partial key is combined with the other half stored on the main server. Of course, everything is done over SSL, even between the two servers. Other limitations will be in place between the two servers, such as restricting only to those two IP addresses as well as limiting the number of decryptions to a certain number (e.g. one every 15 seconds and everything else gets queued - self destruct if the queue reaches a certain number and require admin intervention).

The functionality I am looking for is to have anonymous users able to encrypt new data into the database through the website, all staff members to be able to update existing entries and privileged staff members to be able to decrypt stored data.

Summary of keys and hashes used

Edit - For clarity, there are only two types of keys. Both are asymmetric. I have changed this post and simply called them key1 and key2 for simplicity. Key2 will be xor'ed into two parts, key2a and key2b which combine again to create key2. Key1 is a key encrypting key which encrypts key2. Key2 is used to decrypt the sensitive information.

  • Main server:

    • User password hashes used for authentication, stored in the database.
    • Key1 - Key encrypting key stored temporarily in RAM and stored permanently on the administrator's personal computer and/or flash drive at a completely different location and network
    • key2a keys - Partial private keys stored in database encrypted by the key encrypting key mentioned above (key1).
    • Both public keys for the two private keys above are stored in plain text in the DB.
  • Decryption server

    • Key2b keys - Other halves of the aforementioned partial private keys
  • Key generation:

    • Key encrypting key (key1) can be generated essentially anywhere, probably on the administrator's own PC.
    • The other key pair (key2) is generated by the main server, one for every piece of information to be encrypted.

The encryption process is as follows:

  • A new key2 private and public key pair is generated (a different key pair per sensitive datum)
  • The information is encrypted using key2's public key and stored in the database
  • Key2's private key is then xor'ed into two parts (key2a and key2b).
  • key2a is encrypted using key1's public key and stored in the database
  • key2b is sent to decryption server
  • Decryption server stores key2b in its database and sends back insert ID
  • Insert ID stored in main db

Decryption process:

  • key1 (key encrypting key) stored in memcache (or redis). An administrator must upload this key manually. It will be generated on their own computer. It is stored temporarily in the RAM (until the server goes down) and permanently stored offline on the administrator's computer or flash drive.
  • Non-admin staff member authenticated with their own username and password
  • If they have permission, they can retrieve key1 from the memcache server
  • key1 decrypts the stored half private key key2a
  • key2a and the encrypted data are sent to decryption server along with the respective insert ID
  • Decrypting server then combines key2a and key2b to create key2
  • Key2 then decrypts the information and send it back to the user
  • For key rotation, the decrypted information is then reencrypted using a new key2 pair as outlined in the encryption process

Full key rotation (initiated from decryption server)

I'm not sure if this is necessary, but these are my thoughts. One thing that doesn't sit well with me is that ALL of the data will be momentarily unencrypted (at least in the memory) of the decryption server. As well, I would have to give this server free access to the encrypted data and keys from the main server, which could also open up a whole other can of worms and would basically be game over if this server were ever compromised. I also address this in one of my questions below:

  • Decryption server logs in to main server and requests a full dump of all encrypted data
  • A new key1 key encrypting key pair is generated on the decryption server
  • All encrypted data is decrypted using the old key1
  • A new key2 pair is generated for each piece of decrypted data from the previous step and the data is reencrypted with this key. These are xor'ed into new key2a and key2b.
  • New key2a reencrypted using the new key1
  • Array of newly encrypted data, new key2a and respective ids are sent back to main server and stored directly into DB
  • On main server, new key1 is saved into memcache
  • key1 will need to be sent somehow to the administrator as well so that they can restart the memcache server when it goes down. Since the administrator should have the old key1, perhaps encrypting the new key1 with the old key1 and then simply emailing it to the admin would suffice.

A few things I am unsure about:

  • Is using memcache to store a private key encrypting key secure enough? If not, I'm open to other ideas.
  • For key rotation, is it good practice to rotate all of the keys periodically (both key1 and all key2s) as I have outlined in the "full key rotation" part above, or simply rotate key2s upon use since it is a different key2 for each piece of encrypted data?

Edit :: To answer D.W.'s questions below, I'm not exactly sure how to create a threat model, but I'm assuming you're basically wondering what I am trying to protect against. To be honest, I'm not sure. Essentially, I want only authorized staff members to be able to obtain decrypted data, so whatever that entails, that is what I want to protect against. If either of the servers were compromised, I would want the effect to be either completely mitigated or at least minimized. For example, if someone were to hack the decryption server, they would still need the encrypted data and a partial decryption key. If someone were to hack the main server, they would need the key encrypting key which will be erased from memory if the server goes down; and if the server is still up, they will be limited to a small number of requests per second.

migrated from programmers.stackexchange.com Jul 19 '11 at 20:53

This question came from our site for professionals, academics, and students working within the systems development life cycle.

  • 4
    Welcome to the site. In order to better answer your question we will need some more information. Are you trying to protect the confidentiality (privacy) of the data, the integrity (unmodified) of the data, or both? Where are the servers and are they owned by you, are they physically accessible by you? Who has accounts on the servers? How are you authenticating your users? – this.josh Jul 19 '11 at 21:55
  • I am trying to protect the privacy of the data since staff members will be able to modify it. I never thought about the ownership of the servers. Neither of the servers will be physically accessible. The main server will be on a dedicated server. I had thought about making the decryption server on a shared hosting server, however I could also set up a box in the office instead. Some members of our staff have accounts on the main server with varying permissions. Either they have only encryption privelages or encrypt/decrypt privelages. Authentication is done via username, password and IP. – Mike Jul 20 '11 at 0:45
  • Possible duplicate? security.stackexchange.com/questions/4755/… – Rakkhi Jul 20 '11 at 12:50
  • 2
    OK.. I'm getting lost in the keys while reading this. How many keys are in play here and which key is being used where? I think that you are talking about two sets of keys - 1 asymmetric key pair, and 1 symmetric key pair, but that evil word "private" key is screwing me up. In general, I'd like to know where any key is generated, stored and with what key (if any) its protected. This is probably a point where a picture would help... – bethlakshmi Jul 20 '11 at 14:39
  • @bethlakshmi I apologize for the confusion. I have updated my original post with a summary of where the two key types are stored and generated. – Mike Jul 20 '11 at 16:05

I think your scheme is overly complex. I don't see what security advantages it provides.

  1. If the attacker compromises the memcache server, the attacker can decrypt every ciphertext. (The attacker learns key1 from the memcache memory. The attacker can then learn the stored encrypted key2a and decrypt it with key1. The attacker can then send this, together with the ciphertext, to the decryption server, which will helpfully decrypt it for you.)

  2. If the attacker compromises any machine that authenticates user's passwords, the attacker can decrypt every ciphertext. The attacker just modifies the authentication logic to say "yup, that password is OK!", and then the attacker has all the access needed to initiate the decryption process.

  3. If the attacker compromises the administrator's machine, the attacker learns key2, which is enough to decrypt all the encrypted data.

Basically, I'm not seeing a clear advantage over just storing the key in the clear on a single server and using it to decrypt, without all these contortions.

Of course, it is possible there is something I'm missing. But this is the kind of analysis you should be doing on your own, before asking others to analyze your scheme.

General advice: If you want to design a crypto scheme, it is very important to be clear about what you are trying to achieve. That usually means, you need to understand the security goals (what are you trying to protect?) and the threat model (what kinds of attacks does the system need to resist?). It is usually very helpful to spell this out explicitly. Then, when you think you have a scheme that might be a good idea, your next step is to analyze it: for each of the threats allowed by the threat model, does it achieve your security goals? If you don't know what you're trying to achieve, or if you don't know what the adversary might be able to do, you don't have great odds of designing a secure scheme.

  • Can you maybe give me some sort of example of a threat model for someone trying to protect, for example, social security numbers or credit card numbers? I'm sure this would apply to me as well. – Mike Jul 21 '11 at 21:16
  • 2
    That's probably best as a separate question. Snarkily, the biggest worry for credit card numbers is: "I don't want to flunk the PCI audit". Less snarkily, there's also "I don't want to have a data breach that causes a loss of my customer's credit card numbers (I don't want the embarassment and bad PR, I don't want the expense of cleaning up after it)". These aren't exactly a "threat model", per se, but they typically relate to a hacker who gains access to a server, an authorized insider who misuses their authority, or loss/theft of a backup/copy of the data. – D.W. Jul 22 '11 at 2:26
  • I would like to use the PCI-DSS as at least as a minimum. As I have it, your point #1 is true, which is why I would apply the limits to the decryption server. Then if someone tried to convert the whole database it would at least take a very long time. I thought about also using the user's password as a third part of key2 (i.e. key2c). This would also prevent #1 completely unless the hacker also has an active account too. I'm not sure I get point #2. As for point #3, the hacker would only obtain the key, but not the ability to use it. I could also save the key on a USB drive in a locked safe. – Mike Jul 22 '11 at 22:55
  • I think I am just going to accept this answer. I think that I have basically learned that there is basically no cookie-cutter correct way to do things. I will continue to investigate any potential vulnerabilities whenever I can and try to get them patched right away. As I mentioned earlier, I think it is a good idea to use the user's password as a third part of the key. I know you talk against this here, but it won't be the entire key so I would assume it's ok. – Mike Jul 22 '11 at 23:03
  • Also, thank you for your help. I greatly appreciate it. – Mike Jul 22 '11 at 23:05

There are two standard approaches.

  1. Option 1: Store the private key on the filesystem. You just store the private key in the filesystem (perhaps with filesystem permissions to limit who can access it) on every server that needs access to the private key. You could consider this the "don't sweat it" option.

  2. Option 2: Hardware security modules (HSM). You use a cryptographic hardware security module (HSM) to generate and store the private key. The private key is generated by the HSM and never leaves the HSM. Signature and decryption operations are performed by the HSM, not in software.

How to choose between these two approaches? The first is cheap and simple; its primary drawback is that if any of the server gets compromised, then your private key is toast. HSMs are more expensive, though they offer higher assurance: if your server gets hacked, the hacker might be able to decrypt some previously recorded traffic or sign some messages of their choice for as long as they have access to the server, but they don't learn the private key. Storing the private key on the filesystem means that insiders may be able to steal the private key; HSMs prevent insiders from stealing the private key.

It sounds like you are proposing a complicated scheme that tries to partially address some of the concerns of storing a private key in the filesystem, but I did not really understand your scheme. I will confess that, while I did not really understand what you are proposing or what you are trying to accomplish, I am somewhat skeptical of whether such a scheme makes sense. My past experience with them is that they haven't provided much added security; they've mainly provided obscurity, which obscures the lack of added security. I don't know if that is actually an accurate summary of your particular proposal. If you would like more informed analysis of your particular proposal, I would suggest that you carefully describe (a) what threats you are trying to protect against and what your threat model is, (b) what security goals you are trying to achieve, and (c) how your scheme addresses those threats.

  • Thank you for your response. I apologize for what I was trying to do not being 100% clear. I have updated my original post with a summary of keys used. Hopefully that clarifies a bit. I had never heard of HSMs before, but I will look into them. As for storing on the file system, I didn't want to do this for the same reasons you mentioned. This is why I thought storing it in the RAM using memcache would be a safer approach. That way if the server is compromised it will be in the RAM as opposed to being written to disk. Manual intervention would be required on every reboot to restore the key. – Mike Jul 20 '11 at 16:11
  • I will also try to address the three questions you asked at the end, but I need to investigate what you are asking a bit more, so give me a bit of time. – Mike Jul 20 '11 at 16:16
  • See updated question. – Mike Jul 20 '11 at 19:54

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.