Secure Message #
Secure Message is a lightweight container that can help deliver some message or data to your peer in a secure manner. It provides a simple way to protect your messages and bind them to the credentials of the communicating peers through the use of asymmetric cryptography. Secure Message adds data confidentiality, integrity, and authenticity in one go (a single function call).
Secure Message uses
ANSI X9.62 prime 256v1 aka
NIST P-256 curve.
Themis module-based architecture allows switching to the other curve in the compilation time. Follow #322 issue to learn details.
Some of the features of Secure Message are:
- use of strong cryptography (including ECC)
- message integrity and authentication
- stateless, easy-to-use API
Availability in Themis #
Secure Message is available in all languages supported by Themis:
- React Native
Usage model #
Secure Message assumes that peers have each other’s public key that they trust. Then they can freely exchange any messages with a high level of security and little overhead.
Secure Message comes in two flavours:
- encrypted message – confidentiality, integrity, and authenticity
- signed message – integrity and authenticity, but no confidentiality
Encrypted messages #
Encrypted messages are useful when you need the full stack of protection for your data – in most cases you will be using this flavour. The encrypted message currently uses Secure Cell in Seal mode for data protection.
When elliptic keypairs are used, the intermediate key is derived from the sender and receiver keys with ECDH. Only the sender and receiver can derive the same key, using their private key and the public key of the other party. The key is not included into the message in any way.
RSA keypairs do not support secure intermediate key derivation. In this case Themis generates a new random key of sufficient length, encrypts it for the receiver, and attaches the encrypted key to the message.
In either case, the intermediate key is immediately destroyed by the sender after encrypting the message, so only the receiver can get recover it back for decryption.
Signed messages #
Signed messages are useful for cases where you don’t need data confidentiality. It allows the receiver to verify the origin and integrity of the data while still allowing intermediate nodes to process it accordingly (for example, route data based on its type).
When elliptic keypairs are used, ECDSA is used to sign the message. For RSA keypairs, the RSA+PSS+PKCS#7 digital signature is used.
Implementation details #
Secure Message interface is described in
Generating keypairs #
Parties need to generate keypairs before they can communicate with Secure Messages. New keypairs can be securely generated with Themis key generation functions. Secure Message supports both EC and RSA key pairs.
The API is described in
themis_status_t themis_gen_ec_key_pair( uint8_t* private_key, size_t* private_key_length, uint8_t* public_key, size_t* public_key_length); themis_status_t themis_gen_rsa_key_pair( uint8_t* private_key, size_t* private_key_length, uint8_t* public_key, size_t* public_key_length);
Note: Themis does not support importing pre-existing keys generated elsewhere. This makes it much harder to use weak keys, unknowingly or intentionally provided by third-parties.
The resulting private key must be kept secret, it is used to encrypt and sign outgoing messages, and to decrypt messages sent to you.
Send the public key to the parties you want to communicate with and get their public keys in return. Public keys are used to encrypt outgoing messages and to verify messages sent to you.
Please consult the key management guidelines to learn more about storing and exchanging keys securely after you have generated them.
Encrypting and decrypting messages #
For the encrypt/decrypt mode of Secure Message, use the following API. It requires both private and public keys to be available for both parties. Use your own private key and the public key of the party you are communicating with.
themis_status_t themis_secure_message_encrypt( const uint8_t* private_key, size_t private_key_length, const uint8_t* peer_public_key, size_t peer_public_key_length, const uint8_t* message, size_t message_length, uint8_t* encrypted_message, size_t* encrypted_message_length); themis_status_t themis_secure_message_decrypt( const uint8_t* private_key, size_t private_key_length, const uint8_t* peer_public_key, size_t peer_public_key_length, const uint8_t* encrypted_message, size_t encrypted_message_length, uint8_t* message, size_t* message_length);
Signing and verifying messages #
If you need the sign/verify mode of Secure Message, use the following API. Note that it needs only your private key to sign messages and corresponding public key to verify signatures.
themis_status_t themis_secure_message_sign( const uint8_t* private_key, size_t private_key_length, const uint8_t* message, size_t message_length, uint8_t* signed_message, size_t* signed_message_length); themis_status_t themis_secure_message_verify( const uint8_t* public_key, size_t public_key_length, const uint8_t* signed_message, size_t signed_message_length, uint8_t* message, size_t* message_length);
Thread safety #
Secure Message objects are generally immutable. You can safely use them concurrently from multiple threads. Read more about Themis thread safety guarantees.