# Sym — Light Weight Symmetric Encryption for Humans
[![Gem Version](https://badge.fury.io/rb/sym.svg)](https://badge.fury.io/rb/sym)
[![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/sym?type=total)](https://rubygems.org/gems/sym)
[![Documentation](http://inch-ci.org/github/kigster/sym.png)](http://inch-ci.org/github/kigster/sym)
[![Build Status](https://travis-ci.org/kigster/sym.svg?branch=master)](https://travis-ci.org/kigster/sym)
[![Code Climate](https://codeclimate.com/github/kigster/sym/badges/gpa.svg)](https://codeclimate.com/github/kigster/sym)
[![Test Coverage](https://codeclimate.com/github/kigster/sym/badges/coverage.svg)](https://codeclimate.com/github/kigster/sym/coverage)
[![Issue Count](https://codeclimate.com/github/kigster/sym/badges/issue_count.svg)](https://codeclimate.com/github/kigster/sym)
## Description
> __sym__ is a command line utility and a Ruby API that makes it _trivial to encrypt and decrypt sensitive data_. Unlike many other existing encryption tools, __sym__ focuses on usability and streamlined interface (CLI), with the goal of making encryption easy and transparent. The result? There is no excuse for keeping your application secrets unencrypted :)
## Table of Contents
### Motivation
The primary goal of this tool is to streamline and simplify handling of relatively sensitive data in the most trasparent and easy to use way as possible, without sacrificing security.
Most common use-cases include:
* __Encrypting/decrypting of application secrets__, so that the encrypted secrets can be safely checked into the git repository and distributed, and yet without much of the added headache that this often requires
* __Secure message transfer between any number of receipients__
* __General purpose encryption/decryption with a single encryption key__, optionally itself re-encrypted with a password.
__Sym__ is a layer built on top of the [`OpenSSL`](https://www.openssl.org/) library, and, hopefully, makes encryption more accessible to every-day developers, QA, and dev-ops folks, engaged in deploying applications.
### What's Included
This gem includes two primary components:
* [Ruby API](#ruby-api) for enabling encryption/decryption of any data within any Ruby class, with extremely easy-to-use methods
* [Rich command line interface CLI](#cli) with many additional features to streamline handling of encrypted data.
_Symmetric Encryption_ simply means that we are using the same private key to encrypt and decrypt. In addition to the private key, the encryption uses an IV vector. The library completely hides `iv` generation from the user, and automatically generates a random `iv` per encryption.
### How It Works
1. You start with a piece of sensitive __data__ you want to protect. This can be a file or a string.
2. You generate a new encryption key, that will be used to both encrypt and decrypt the data. The key is 256 bits, or 32 bytes, or 45 bytes when base64-encoded, and can be generated with `sym -g`.
* You can optionally password protect the key with `sym -gp`
* You can save the key into a file `sym -gp -o key-file`
* Or you can save it into the OS-X Keychain, with `sym -gp -x keychain-name`
* or you can print it to STDOUT, which is the default.
3. You can then use the key to encrypt sensitive __data__, with `sym -e [key-option] [data-option]`, passing it the key in several accepted ways:
* You can pass the key as a string (not recommended) via `-k key`
* Or read the key from a file `-K key-file`
* Or read the key from the OS-X Keychain with `-x keychain-name`
* Or you can paste the key interactively with `-i`
4. Input data can be read from a file with `-f file`, or read from STDIN, or a passed on the command line with `-s string`
4. Output is the encrypted data, which is printed to STDOUT by the default, or it can be saved to a file with `-o `
5. Encrypted file can be later decrypted with `sym -d [key-option] [data-option]`
Sample session that uses Mac OS-X Keychain to store the password-protected key.
```bash
❯ sym -gpx my-new-key
New Password : •••••••••
Confirm Password : •••••••••
BAhTOh1TeW06OkRhdGE6OldyYXBwZXJTdH.....
❯ sym -ex my-new-key -s 'My secret data' -o secret.enc
Coin::Vault listening at: druby://127.0.0.1:24924
Password: •••••••••
❯ cat secret.enc
BAhTOh1TeW06OkRhdGE6OldyYXBFefDFFD.....
❯ sym -dx my-new-key -f secret.enc
My secret data
```
The line that says `Coin::Vault listening at: druby://127.0.0.1:24924` is the indication that the local dRB server used for caching passwords has been started. Password caching can be easily disabled with `-P` flag. In the example above, the decryption step fetched the password from the cache, and so the user was not required to re-enter the password.
__Direct Editing Encrypted Files__
Instead of decrypting data anytime you need to change it, you can use the shortcut flag `-t` (for "edi__T__"), which decrypts your data into a temporary file, automatically opening it with an `$EDITOR`.
Example:
sym -t -f config/application/secrets.yml.enc -K ~/.key
> This is one of those time-saving features that can make a difference in making encryption feel easy and transparent.
For more information see the section on [inline editing](#inline).
## Installation
If you plan on using the library in your Ruby project with Bundler managing its dependencies, just include the following line in your `Gemfile`:
gem 'sym'
And then run `bundle`.
Or install it into the global namespace with `gem install` command:
$ gem install sym
$ sym -h
$ sym -E # see examples
__BASH Completion__
Optionally, after gem installation, you can also install bash-completion of gem's command line options, but running the following command (and feel free to use any of the "dot" files you prefer):
sym --bash-completion ~/.bashrc
Should you choose to install it (this part is optional), you will be able to use "tab-tab" after typing `sym`, and you'll be able to choose from all of the supported flags.
## Using `sym` with the Command Line
### Private Keys
The private key is the cornerstone of the symmetric encryption. Using `sym`, the key can be:
* generated and printed to STDOUT, or saved to Mac OS-X KeyChain or a file
* fetched from the Keychain in subsequent operations
* password-protected during generation (or import) with the `-p` flag.
* must be kept very well protected and secure from attackers.
The __unencrypted private__ key will be in the form of a base64-encoded string, 45 characters long.
__Encrypted (with password) private key__ will be considerably longer, perhaps 200-300 characters long.
When the private key is encrypted, `sym` will request the password only once per 15 minute period. The password is cached using a local dRB server, but this caching can be disabled with `-P` flag.
#### Generating Private Keys
Let's generate a new key, and copy it to the clipboard (using `pbcopy` command on Mac OS-X):
sym -g | pbcopy
Or save a new key into a bash variable
KEY=$(sym -g)
Or save it to a file:
sym -g -o ~/.key
sym -go ~/.key
Or create a password-protected key (`-p`), and save it to a file (`-o`), and skip printing the new key to STDOUT (`-q` for quiet):
sym -gpqo ~/.secret
New Password: ••••••••••
Confirm Password: ••••••••••
You can subsequently use the private key by passing either:
1. the `-k key-string` flag
2. the `-K key-file` flag
3. the `-x key-keychain-name` flag to read the key from Mac OS-X KeyChain
4. pasting or typing the key with the `-i` (interactive) flag
#### Using KeyChain Access on Mac OS-X
KeyChain storage is a huge time saver. It allows you to securely store the key the keychain, meaning the key can not be easily extracted by an attacker without a login to your account. Just having access to the disk is not enough.
Apple had released a `security` command line tool, which this library uses to securely store a key/value pair of the key name and the actual private key in your OS-X KeyChain. The advantages of this method are numerous:
* The private key won't be lying around your file system unencrypted, so if your Mac is ever stolen, you don't need to worry about the keys running wild.
* If you sync your keychain with the iCloud you will have access to it on other machines
To activate the KeyChain mode on the Mac, use `-x ` field instead of `-k` or `-K`, and add it to `-g` when generating a key. The `key name` is what you call this particular key, based on how you plan to use it. For example, you may call it `staging`, etc.
The following command generates the private key and immediately stores it in the KeyChain access under the name provided:
sym -g -x staging
Now, whenever you need to encrypt something you can specify the key with `-x staging`.
Finally, you can delete a key from KeyChain access by running:
keychain delete
Below we describe the purpose of the executable `keychain` shipped with sym.
#### KeyChain Key Management
`keychain` is an additional executable installed with the gem, which can be used to read (find), update (add), and delete keychain entries used by `sym`.
It's help message is self-explanatory:
Usage: keychain [ add | find | delete ]
#### Moving a Key to the Keychain
You can easily move an existing key from a file or a string to a keychain by combining -k or -K to read the key, with -x to write it.
sym -k $mykey -x mykey
#### Adding Password to Existing Key
You can add a password to a key by combining one of the key description flags (-k, -K, -i) and then also -p.
sym -k $mykey -p -x moo
The above example will take an unencrypted key passed in `$mykey`, ask for a password and save password protected key into the keychain with name "moo."
#### Encryption and Decryption
This may be a good time to take a look at the full help message for the `sym` tool, shown naturally with a `-h` or `--help` option.
```
Sym (2.1.1) – encrypt/decrypt data with a private key
Usage:
# Generate a new key:
sym -g [ -p ] [ -x keychain ] [ -o keyfile | -q | ]
# Encrypt/Decrypt
sym [ -d | -e ] [ -f | -s ]
[ -k key | -K keyfile | -x keychain | -i ]
[ -o