Key management
In current version of Themis, key management is left at consideration of end-user. However, we've got some advice and helpful tips for those willing to do truly secure development. Doing highest level of cryptography is negligible if your keys are not protected well.
Generating keys
A good key should be as random as possible.
Do not "contruct" keys yourself or use "secret strings" as keys directly. If possible, use strong random number generator to generate keys. If you really need to use a secret password, pass it through a key derivation function (one-way hash function which will make it look like a random key).
The idealistic way to generate long-term keys (any key which is used more than once is considered a long-term key) is to use a dedicated machine or device which is located in a separate room, not connected to the network (even private or corporate) and allows only authorized personell to administer it. Of course, there will be some simplifications in a way you will do it.
If possible, verify your random number generator with some statistical test suite (currently we use NIST STS to check RNGs). While passing statistical tests does not guarantee that you RNG is good, failing them surely proves it is bad and predictable.
You can use our key generation function (derived from OpenSSL) to generate your keys.
Storing keys in your application
Generally we recommend to use ephemeral (one-time) keys for encryption whenever possible and only use signature keys as long-term keys. Regardless of the key type, applications must not store the keys in plaintext (as is) on persistent storage. While using well defined policy and operating system access control mechanisms to limit access to key files is a good (and absolutely necessary thing) to do, storing them in encrypted form makes overall security level of your solution much higher.
The simplest way, which requires little effort and no infrastructure, you can go is to use some kind of a master password to encrypt all your keys in the application. Master password can be passed as some parameter on application startup and you can use secure cell to protect all keys and other sensitive data.
Signature keys vs encryption keys
Do not use same asymmetric keys for signature and encryption (or key agreement). While mathematically they are same thing and you may be tempted to simplify your key management scheme, their purpose is what makes them different:
-
Encryption (or key agreement) keys are used to protect data (or other keys). Loosing such key will definitely lead to loosing all data protected with this key. That's why most probably you would like to keep several copies of this key on different backup media. Also, access to this key may be granted to several people (for example, backup security officer needs to access the key when primary administrator is on unexpected sick leave). So, main aspects of this type of keys are: replicated, shared usage, critical not to loose.
-
Signature keys, on the other hand, are used to prove an identity (of a person or a computing node) in various authentication mechanisms. Loosing such key will not cause any data to be lost. These keys can be relatively easily replaced: you just have to notify all verifying parties that they should not trust the old key anymore and they should trust the new key instead. And, by carefully using timestamps, they can still trust the old data which was signed by the old key before such notification. But, since such key represents an identity, sharing or replicating it increases security risks, because each user of the key may impersonate this identity. That is why you would probably want to limit the number of potential users of signature keys as much as possible. For signature keys, which represent a person's identity there should be only one user - the person whose identity the key is representing. For machine keys we recommend not more than two people which are very trusted within their security domain. So, mostly, signature keys are: not replicable, single usage, affordable to loose, replacable.
As you may see from above, contradicting use-cases and scenarios is what makes those keys different, so keep it in mind while designing your key hierarchy and key management scheme. Also, don't forget to store those keys in encrypted form regardless of key type.
Exchanging keys and transmitting keys over the network
The first recommendation may seem obvious: do not send the keys in plaintext over the network. Always encrypt them. But some usually forget about the second recommendation: even if you exchange public keys only, you should ensure their integrity and authentity, because if you do not - man-in-the-middle (MiTM) will take over all your communications.
Relying on integrity through encryption - is bad practice, so use a separate integrity mechanism.
Both secure message and secure session ensure confidentiality, integrity and authentity of the transmitted data, so they can be used to send/receive keys as well.