1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
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).
|