9

I am writing an application App1. This application uses SQLite database and I plan to encrypt it using AES256. For symmetric encryption I need a key, which I need to store somewhere.

From a similar questions I have a few options, but none is applicable in my case:

  1. Tie the encryption key to your admin login

    I don't trust the currently logged user. In fact, I want to hide this from anyone, but App1.

  2. Tie the encryption key to your hardware.

    App1 is deployed to thousands of machines, some may not have needed hardware.

  3. Type in the encryption key when you start up, store it in memory.

    User must not have access to App1 key.

  4. Store the key on a different server.

    Machine is allowed to be off line, while App1 is running.

  5. Store the key elsewhere on the same server.

    Then it can be found.

  6. Store the key in the database.

    I need to secure the database, which is kind of recursive in my case.

Possible solution is to store the key using Windows DPAPI, but

  1. DPAPI is focused on providing data protection >for users<.

    Whereas I need to protect an application. I also need that App1 worked from different users on the same machine

  2. I can add secondary entropy, to restrict the currently logged user from accessing the data.

    However, I need to store this secret data on the machine. How do I protect that... Appears to be recursion again.

Question: where do I securely store application-specific symmetric key?

oleksii
  • 1,046
  • 1
  • 9
  • 19
  • 9
    Sounds like you need some magic fairy dust. –  Mar 14 '13 at 15:18
  • 4
    Pick two: 1) untrusted user 2) secret data on the client 3) secure – CodesInChaos Mar 14 '13 at 15:27
  • @CodesInChaos - #1 should really be untrusted users with control of client computer. There are at least a few options if you can lock down the system to limit the ability of the untrusted user on the client system, though it is probably too complex to answer in QA format. – AJ Henderson Mar 14 '13 at 15:34
  • possible duplicate of [where to store a key for encryption](http://security.stackexchange.com/questions/12332/where-to-store-a-key-for-encryption) – AJ Henderson Mar 14 '13 at 15:35
  • 1
    @AJHenderson This is a different question: I am asking for **application-specific** key storage. – oleksii Mar 14 '13 at 15:37
  • @Oleksii - the questions are fundamentally the same in regards to the technical challenges. Both require a key to be stored in such a way that a user can't get it but an application can. The question of where to store a key for a server to connect to a DB without someone with control of the server being able to get it is the same as where to store a key for a client application without the user of the computer being able to get it. – AJ Henderson Mar 14 '13 at 16:13
  • If an application running on my machine has access to something, I also have access to it. – lynks Mar 15 '13 at 00:45
  • @lynks strictly speaking that is not true. For example DRM protected video. An application has a read access, but is not able to copy the media. Another example would be an ACL controlled folder with a centrally controlled environment where user usually has limited privileges. – oleksii Mar 15 '13 at 08:36
  • @oleksii lynks clearly assumes a privileged user. In that case your DRM example doesn't work, since an application that can read and decrypt the data can always be modified to create a copy of the plaintext. You can just throw loads of obfuscation at the problem, increasing the amount of work required to do so. – CodesInChaos Mar 15 '13 at 09:11
  • You can derive the key from compiled binary of your application itself (or even better, memory image so that on-the-fly changes can be masked as well). Any modification will invalidate the key unless some form of collision is found. – Maxthon Chan May 17 '14 at 13:24

5 Answers5

5

This is the magical issue of DRM and the short answer is that there is no good answer and if you come up with one, you will be very wealthy. In order for the application to access the key, it has to be able to get to it from an unencrypted state and whatever it can do, a sufficiently advanced user can do too.

You could use a TPM (trusted platform module) or HSM (hardware security module) to store the key as long as the user does not have administrative access on the system, but if they are an admin, then they will likely be able to get the TPM or HSM to give up the key. It would also be difficult to make sure that only the program is able to get the TPM or HSM to perform operations as the application has no way to authenticate itself to the key store that the user can't fake, but it at least would keep the key itself safe.

So short answer, you are completely out of luck if the users have admin on the box the app will run on. If you can give them only limited accounts, then there are some options, but they are still not particularly strong unless you lock down the system quite a bit.

AJ Henderson
  • 41,816
  • 5
  • 63
  • 110
  • 1
    "they will likely be able to get the TPM or HSM to give up the key" Those are usually write-only i.e. you can import but not export keys. So unless you're an expert in hardware analysis (like flylogic) you won't be able to extract the key. Obviously this requires a pre-loaded key by a trusted third party, and an attacker will probably still be able to steal the plaintext, just not the key. – CodesInChaos Mar 14 '13 at 15:45
  • @CodesInChaos - I was under that impression as well but have seen at-least one TPM where it was exportable with admin access and control of the TPM. It probably depends on the exact hardware, but at-least some will allow export if you authenticate with the chip as administrator. Perhaps there is a no-export setting that can be set on it though. – AJ Henderson Mar 14 '13 at 16:10
  • Many proprietary corporate software comes with encryption dongles for anti-piracy purpose. It is perhaps the only way to secure data on a per-application bases. But fundamentally the data or key will exist as plain text in memory at some point and there's no way to completely protect memory. – billc.cn Mar 15 '13 at 01:13
1

HSM would be a good way to go. Unfortunately I am not aware of any FOSS implementations. I have occasionally considered doing my own "good enough/far better than nothing" HSM. It wouldn't be FIPS certified or encased in epoxy with security seals but it would be better than having a key just sitting on a box.

The nice thing about HSM is that you can audit access to the key independently of the host requesting/using the key. If the key was retrieved during a time when there was no machine rebooting or process that needs it starting you would have grounds for an investigation and perhaps changing the key.

Since your most likely solution is going to be storing the key in a secret place on the server I recommend using SELinux to protect the key from being read by all but approved users/security contexts.

I also recommend using auditd to place special audit rules on the file containing the key so that you can keep track of whenever the file is read. Sending the audit logs off-host to a log collection host is highly recommended. This gets you some of the auditability of having an HSM.

Tracy Reed
  • 618
  • 4
  • 5
0

What about the following?

1) creating a public/private key pair.

2) encrypt your symmetric key with the public key, and store that in the code.

3) present your private key at startup to be read in by the program (copy / paste to the command line).

The disadvantage of this is that the process is manual, and the "owner" has to be the guy starting the program up.

The advantage, is it does give you the security, in that the private key goes into local memory and, if coded right, can be deleted this once it's used to decrypt (in java, use a byte[] then clear it out).

will
  • 1
0

Windows Cryptographic Service Provider key store can only store asymmetric keys. Why Microsoft designed it this way is a very good question. Being it that may, your only solution is to use an HSM. You would store your application keys in a data store you create and encrypt it with a master key, which is stored in the HSM.

Most modern HSMs supports PKCS#11 syntax for API calls. HSMs are available as PCI Cards and standalone boxes. You need to also consider your overall
crypto needs before selecting the PCI or standalone option.

You would also separate the HSM admin functions from the server and database admins. You achieve separation of duties, which is basic InfoSec principle when you start dealing with application encryption and sensitive data.

Keep in mind, encryption is technique, anyone can encrypt by calling Crypto Service Provider APIs. Cryptography is the whole process of securely generating keys, securely ciphering and deciphering data, securely storing keys, preventing unauthorized access and rotating keys. Applying encryption haphazardly gives you a false sense of security.

0

It depends.

Requirement 2 eliminates any hardware based solutions including HSM.

You have not precisely described from what kinds of users do you want to protect it from. You wrote I want to hide this from anyone. If by anyone you mean also system admins, then there is no solution. If you mean users with less privileges, not admins, then there can be a solution. You can create a resource (file, registry entry, ...) and store your key there. Give access to this resource only to the account your application is running under. Then such your users (except admins) will not be able to get access to your key. But admins will still be able to change permissions and to get access to your key.

mentallurg
  • 8,536
  • 4
  • 26
  • 41