Shick Crypto Library
This library shows how to use NaCl in form of libsodium to securely encrypt a message with asymmetric encryption.
In German, Schick! (pronounced [shick]) means Send!. So, clone and start sending securely. You can find Shick Crypto Library
Please feel free to clone and adapt to your needs. If you find any bugs or have enhancements, please share it. I will react on pull requests promptly.
How Does it Work
Shick Crypto Library is just a thin wrapper around libsodium. The main functionality consists of two functions, i.e.,
shick_crypto_dec_message. Messages are encrypted and decrypted following the same pattern as used in GPG by generating a random symmetric key, encrypting a message symmetrically, and finally encrypt the random key asymmetrically. Since asymmetric encryption is computational more expensive than symmetric encryption, this pattern combines the security and speed of both worlds. In addition, all encryption, i.e., asymmetric and symmetric encryption, is protected by MACs and initialized with nouces. The concrete algorithms used by NaCl are currently Curve25519 elliptic curve cryptography for asymmetric encryption, Salsa20 for symmetric encryption, and Poly1305-AES for message authentication code (MAC) computation.
How to Use
Check is usually available on all Linux distributions and in Homebrew. libsodium might be available, but please make sure you use a recent version. It is easy to install from source -- see their Readme. If you compile from source, please make sure to pass the parameter
./configure in order to use
/dev/random for random number generation.
autoreconf --install && ./configure && make
make checkfor acceptance and unit tests
./configure --enable-gcov && make clean && make && make checkfor coverage test
Shick Crypto Library has six functions:
// Returns Shick Crypto Library version const char* shick_crypto_version()
// Initializes libsodium and should be run once per application run void shick_crypto_init()
// Creates an asymmetric key pair int shick_crypto_create_asymmetric_key_pair(secret_key, public_key)
// Creates a random nonce of specific length void shick_create_nonce(nonce, len)
// Encrypts a message with a random symmetric key and encrypts this key asymmetrically for all recipients int shick_crypto_enc_message(sender_secret_key, recipient_public_keys, amount_of_recipients, message, message_len, nonce, encrypted_symmetric_keys, ciphertext)
// Decrypts a message with a asymmetrically encrypted symmetric key int shick_crypto_dec_message(recipient_secret_key, sender_public_key, encrypted_symmetric_key, ciphertext, cipertext_len, nonce, message)
The results to send to each recipient are the chosen nonce, the encrypted symmetric key for the particular recipient, and the ciphertext.
This example is an excerpt from the example in examples/examples1.c. See there for a full example.
SC_CHAR message = "Shick Crypto Lib"; // Message to send int amount_of_recipients = 1; // Number of recipients const SC_CHAR* recipient_public_keys[amount_of_recipients]; // List of recipients // Buffer Alice' and Bob's key pairs SC_CHAR alice_secret_key[crypto_box_SECRETKEYBYTES]; SC_CHAR alice_public_key[crypto_box_PUBLICKEYBYTES]; SC_CHAR bob_secret_key[crypto_box_SECRETKEYBYTES]; SC_CHAR bob_public_key[crypto_box_PUBLICKEYBYTES]; // Buffers for nonce, ciphertext, and encrypted symmetric keys SC_CHAR nonce[crypto_box_NONCEBYTES]; SC_CHAR ciphertext[crypto_box_MACBYTES + sizeof message]; // Space for MAC SC_ENC_SYM_KEY encrypted_symmetric_keys[amount_of_recipients]; SC_CHAR message_decrypted[sizeof message]; // Buffer for roundtrip decrypted message shick_crypto_init(); // Init libsodium // Create Alice' and Bob's key pairs shick_crypto_create_asymmetric_key_pair(alice_secret_key, alice_public_key); shick_crypto_create_asymmetric_key_pair(bob_secret_key, bob_public_key); recipient_public_keys = bob_public_key; shick_create_nonce(nonce, sizeof nonce); // Create nonce for asymmetric encryption // Encrypt and sign from Alice to Bob shick_crypto_enc_message(alice_secret_key, recipient_public_keys, amount_of_recipients, message, sizeof message, nonce, encrypted_symmetric_keys, ciphertext); // Now your message is encrypted for Bob and Bobby // Send (nonce, encrypted_symmetric_keys[i], ciphertext) to Bob and Bobby // Decrypt and verify signature for Bob from Alice shick_crypto_dec_message(bob_secret_key, alice_public_key, encrypted_symmetric_keys, ciphertext, sizeof ciphertext, nonce, message_decrypted);