libsecrecy
==========

libsecrecy is a header only C++17 library implementing an encrypted file
format based on GCM (Galois Counter Mode) and AES128 or AES256.

It uses [nettle](http://www.lysator.liu.se/~nisse/nettle/) routines for file
encryption and decryption via GCM using AES128 or AES256 as cipher function
and [gpgme](https://gnupg.org/software/gpgme/index.html) for key storage.

While encryption is currently only supported in a streaming fashion,
decryption allows random access in the encrypted file due to independently
encoded subunits.

# Compilation

libsecrecy uses the GNU autoconf/automake tool set. It can be compiled on Linux
using:

	libtoolize
	aclocal
	autoreconf -i -f
	./configure
	make

Running autoreconf requires a complete set of tools including autoconf, automake,
autoheader, aclocal and libtool. Use

	./configure --prefix=$HOME/libsecrecy
	make install

to obtain a local installation.

Compiling libsecrecy requires nettle, gpgme and pkg-config to be installed.
On Debian and Ubuntu this can be done by installing the packages nettle-dev,
libgpgme-dev and pkg-config.

# Command line tool

The distribution comes with a command line tool called secrecy. This tool
currently has three subcommands createKey, encrypt, decrypt, exportKey,
importKey, listKeys and setDefaultKey.

---

Keys for libsecrecy can be created using the command

	secrecy createKey cipher gpgid keyname

where cipher can currently take the values AES128, AES192 or AES256, gpgid needs
to be a valid id (e.g. email adress) present as a secret key in gpg's
keyring which can be used for securely storing the AES key for use by
libsecrecy and keyname can be chosen as a human readable name for the key
create (e.g. mykey).

See https://gnupg.org/documentation/manuals/gnupg/OpenPGP-Key-Management.html#OpenPGP-Key-Management
for creating and handling gpg keys.

The program outputs a key hash in the form of a hexadecimal encoded string.
Either this key hash or the key name given can to be provided to the encrypt command of secrecy for
encrypting files using the newly created key.

---

Files can be encrypted using the encrypt command of secrecy. The syntax for
this is

	secrecy encrypt keyhash/name < input.plain > output.encryped

Keyhash/name is either the hex string which was printed by createKey when creating the
key or the name given to createKey when creating the key. If the string
provided is empty, then the default key name is used (see setDefaultKey), if
any has been set.

Note that this command needs to decrypt the key from it's gpg encoded form,
so you will need to provide the respective passphrase in some form.

---

Encrypted files can be decryped using the decrypt command of secrecy. The
respective syntax is

	secrecy decrypt < input.encrypted > output.plain

This command also needs to decrypt the key from it's gpg encoded form,
so you will need to provide the respective passphrase in some form.

Note that you do not need to provide the keyhash for decryption as this
information is provided inside the encrypted file.

---

Keys can be exported to an encrypted transfer format for passing data on to
third parties via the exportKey command of secrecy. The syntax for this is

	secrecy exportKey keyname gpgid > exported_key.txt

where keyname is a valid key name or hash and gpgid is a string identifying
the recipient of the key. The public key of gpgid needs to be available in
gpg's key database.

---

Keys can be imported from the format produced by the exportKey command using
the importKey command. The syntax is

	secrecry importKey gpgid < exported_key.txt

where gpgid designates the gpg key which will be used to locally encrypt the
key for storing it in libsecrecy's database.

---

The list of installed keys can be shown using

	secrecy listKeys

which prints a tab separated table such that the first column contains
the key names and the second the respective key hash values.

---

The default key can be set using

	secrecy setDefaultKey keyname

The default key is used when an empty keyname string is used for running
any command accepting a key name (with the obvious exceptions of
createKey and setDefaultKey).

# Key storage

AES keys are stored encrypted using gpg via gpgme. Each key is assigned
a hash H value at creation time. H is computed as the SHA256 checksum of
a randomly generated sequence. Keys are stored and searched for in the
directory set in the environment variable `LIBSECRECY_KEYDIR`. If this
variable is not set, then the subdirectory .libsecrecy inside the current
users home directory (designated by the environment variable HOME) is used.
Inside this directory the key for hash H is stored in the file
hash/H (e.g. `hash/3E35C013C66C66B09E3E0B923451530C62D4346D9F5165906FC94B9B4D35E28E`)
where the respective files are encrypted using gpgme. The secret key used
for this encryption can be set at key creation time.

# Compiling your own program using the installed library

After installing libsecrecy in e.g. `$HOME/libsecrecy`, the flags required for
using the library can be acquired using the pkg-config tool via

	PKG_CONFIG_PATH=$HOME/libsecrecy/lib/pkgconfig pkg-config libsecrecy --cflags --libs

A simple example decryption program is

```
#include <libsecrecy/GCMInputStream.hpp>
#include <iostream>

int main()
{
	libsecrecy::GCMInputStream GIS(std::cin);
	static std::size_t const buffersize = 16*1024;
	char B[buffersize];

	while ( GIS )
	{
		GIS.read(&B[0],buffersize);
		std::cout.write(&B[0],GIS.gcount());
	}
}
```

A simple encrypytion example program is

```
#include <libsecrecy/GCMOutputStream.hpp>
#include <iostream>

int main()
{
	std::string const scipher = "AES256";
	std::string const shexhash = "3E35C013C66C66B09E3E0B923451530C62D4346D9F5165906FC94B9B4D35E28E";
	libsecrecy::GCMOutputStream GOS(std::cout,scipher,shexhash);
	static std::size_t const buffersize = 16*1024;
	char B[buffersize];

	while ( std::cin )
	{
		std::cin.read(&B[0],buffersize);
		GOS.write(&B[0],std::cin.gcount());
	}
}
```

Obviously you need to provide a value obtained using secrecry's createKey
command as `shexhash`.

# License

libsecrecy is provided under a simplified (2 clause) BSD license (see COPYING).
