Skip to content

SimpleBox

Tony Arcieri edited this page Dec 24, 2016 · 7 revisions

The RbNaCl::SimpleBox class provides a simple, easy-to-use cryptographic API where all of the hard decisions have been made for you in advance. If you're looking to encrypt something, and you don't know much about cryptography, this is probably what you want to be using.

RbNaCl::SimpleBox takes care of "nonce" handling for you, i.e. generating some random data associated with each message to make it unique, even if you encrypt the same message twice. You may not be aware that this is important, but it is, and this class handles it automatically by using a secure random data source.

Creating a SimpleBox

RbNaCl::SimpleBox provides two different APIs for creating boxes, one for secret-key encryption (a.k.a. symmetric encryption), and another for public-key encryption (a.k.a. asymmetric encryption). Here's a brief synopsis of the difference:

  • Secret-key encryption: We want to encrypt a message with a key, and decrypt the message later with the same key
  • Public-key encryption: We have two people or software systems that want to send encrypted messages to each other. Each of them has both a public and private key. The sender first obtains the recipient's public key, then encrypts the message from her secret key to his private key. The recipient obtains her private key and the message, and is able to decrypt it with his secret key. Once the message is decrypted, the sender knows the message is authentic and was sent from someone who had the sender's private key.

Once we've created a RbNaCl::SimpleBox, the API is the same for both secret-key and public-key encryption. The main difference is the constructor:

Secret-key Encryption with SimpleBox

To create a SimpleBox for secret-key encryption, we can use the following code:

box = RbNaCl::SimpleBox.from_secret_key(key)

We'll need to generate a key first, though! To do that, we can use RbNaCl's built-in random number generator:

key = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)

Public-key Encryption with SimpleBox

To create a SimpleBox for public-key encryption, we can use the following code, which assumes we're the sender and her name is Alice, and the recipient is Bob:

Alice's Perspective (Sending)

# We'll first generate a random private key for ourselves (even though we're just the sender)
alice_private_key = RbNaCl::PrivateKey.generate

# Next we need to send this to the recipient over a secure channel. Some pseudocode:
send_public_key_to_bob(alice_private_key.public_key)

# We'll also need to get Bob's public key over a secure channel somehow. Pseudocode:
bob_public_key = get_recipient_public_key

# Alice can now make a Simplebox for sending messages to Bob
box = RbNaCl::SimpleBox.from_keypair(bob_public_key, alice_private_key)

Bob's Perspective (Receiving)

# We'll first generate a random private key for ourselves
bob_private_key = RbNaCl::PrivateKey.generate

# First we need to get Alice's public key over a secure channel
alice_public_key = get_sender_public_key

# Next we need to send Alice our public key over a secure channel
send_public_key_to_alice(bob_private_key.public_key)

# Once we've done that, Bob too can make a box for receiving messages
box = RbNaCl::SimpleBox.from_keypair(alice_public_key, bob_private_key)

Encrypting with SimpleBox

The beauty of SimpleBox is once you've created one, encryption is simple:

ciphertext = box.encrypt(plaintext)

That's it! You now have a ciphertext you can safely send to a 3rd party. While many Ruby libraries try to offer this sort of API, RbNaCl is one of the very few that actually gets it correct.

Decrypting with SimpleBox

Once you've created a SimpleBox, the decryption API is similarly simple to encryption:

plaintext = box.decrypt(ciphertext)

If ciphertext has been tampered with, this method will raise RbNaCl::CryptoError

RDoc