I'm learning about security at the moment and one thing I'd like to try out is having a key server distribute keys to clients that will allow them to securely save and read data locally.

My basic idea is that the client will communicate with the server over TLS where they'll provide a username and password. This password will be used to both authenticate the user and decrypt the key in the database.

Essentially the key server database would be laid out like so:

| User Name | Hashed Password+Salt | Salt | Encrypted Key |

In this case, would the keys be secure in the event of a database leak? I'm wondering if there is a best practice for this kind of implementation or should I handle this differently?

  • So, users can only read the encrypted files if, and only if, they have an active connection to your server? Why, then, store the files locally? Why not store the files themselves on the server where you have much better control over the protection?
    – schroeder
    Apr 14, 2014 at 15:31
  • The reason for storing them locally was that the data could be reletively large (200MB+) so I didn't want to have to transfer them every time. The user would be running custom natual language processing algorithms on this data which could be CPU intensive and I'd rather distribute that work out among the users than run it centrally.
    – Eoin Nolan
    Apr 16, 2014 at 11:08
  • It would be more secure to simply send the encrypted data to the user and let them unencrypt it with their key.
    – Red Alert
    Jun 9, 2014 at 22:22

3 Answers 3


(Disclaimer: I'm a "security student" myself, so I'm not 100% sure if this is correct.)

I don't understand why you would want to keep private keys on the server after they are transferred to the user. There is no use for them. If they are lost - create new ones.

Keys have a public and a private part. The public part can really be public and may be published on the web.

Private keys should be kept private, and this should mean that users have their keys on their own machine (laptop, phone etc), maybe even a unique key for each machine. They should be instructed how to keep that key safe there. A password comes to mind. If you create the keys for the user on your server, you need a way to get the private key safely to the user. This can be done locally, over SSH, or via USB stick, etc. Create the keys right before you transfer them, then delete them.

Maybe I'm missing something, a good reason to keep the keys on the server - then please explain why.

  • Apologies, I wasn’t very clear. The keys on the server are AES keys, or some other form of symmetric crypto key. The reason they are on the server is so the user may retrieve their key and decrypt their local files. I’m trying to protect against the case of their device being stolen or compromised and having the key present along with the encrypted data.
    – Eoin Nolan
    Apr 10, 2014 at 20:55
  • If the device is stolen, block the keypair on the server. Then it can't be used to access info on the server anymore. If data on the stolen laptop is encrypted with the key, and can be decrypted with the key, make sure the key is protected with a password. If it's really sensitive data, encrypt the harddrive.
    – SPRBRN
    Apr 10, 2014 at 21:15
  • 1
    Actually you're missing the difference between asymmetric and symmetric (used in op's design) cryptography. There is no key pair involved here. Juste one key used both for encryption and decryption. There's lots of high quality papers on that topic you'll find online. I strongly advise you to read a couple ones
    – ero
    Jul 10, 2014 at 0:00

Complexity is the enemy of security. So is giving up control of the valuable bits, like keys, when it isn't necessary.

As I understand it, your scheme works something like this:

  1. User starts client app that can access encrypted local files
  2. User enters a) username and b) password
  3. User name and password are transmitted to server
  4. Server authenticates user with username and password
  5. Server uses a KDF to derive an encryption key from user's password
  6. Server decrypts user's stored key using the derived key
  7. Server transmits decrypted key back to the client app
  8. Client app decrypts the files using the key

However, all you really need is 1, 2b, 5, and 8. Steps 2a, 3, 4, 6, and 7 are unnecessary and simply add risk.

In the simpler model:

  1. User starts client app that can access encrypted local files
  2. User enters password
  3. The local client app uses a KDF to derive an encryption key from user's password
  4. Client app decrypts the files using the key

In this model, there is no persistent key storage required, no server holding a treasure trove of encrypted keys and hashes that could be attacked and used to brute-force password, no Internet transmission of sensitive data.

Your question doesn't mention any particular reason to want or need a server that stores keys. Absent that need, I think you should rethink your threat model, because the current design doesn't make a lot of sense to me.


Your keys might be safe, depending among others on the encryption used and how strong user passwords are. But there's a way to make it much safer : don't store them.

In your system as you describe it, there is no reason not to let the client take care of the whole encryption/decryption. Thus, the server has no point in knowing user encryption keys. Storing the keys on your server will actually add substantial and unnecessary risks :

  • your server can be hacked, your database stolen and the keys retrieved

  • you have to send these keys over your network, where they may be intercepted

The only (although bad) reason I can see for you to want to store user keys in database is to be able to send it back if a client loses its key. However this shouldn't concern you as it isn't supposed to happen. Storing a private key is a very sensitive matter that should be handled extremely carefuly. It's not something you "just lose".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .