authenticated encryption on the commandline using a chunked construction similar to intermaclib
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
ae
assets
chunkstream
cli
docs
keyderivation
padding
.gitattributes
.gitignore
.travis.yml
CHANGELOG.md
LICENSE
README.md
SPECIFICATION.md
go.mod
go.sum
magic
main.go
makefile
version.sh

README.md

aenker

Build Status CodeFactor codebeat badge

aenker is a simple commandline utility to encrypt files to a public key (Curve25519) with an authenticated encryption scheme (ChaCha20Poly1305). This is basically an ECIES.

The input is split into smaller chunks internally and is encrypted & authenticated individually. Padding and concatenation is done similarly to InterMAC. The key used for encryption is derived with HKDF using Blake2b after performing anonymous Diffie-Hellman with a given public and a random ephemeral private key. All this is further described in the specification.

There is a small decryption script written in Python. It should provide an easily readable overview of the inner workings.

Authenticated encryption authenticates the ciphertext upon decryption and combined with the above construction any chunk reordering, bit-flips or even truncation can be detected and are shown as errors. Only ciphertext that has been successfully decrypted and authenticated is ever written to the output. The chunking still alleviates the need to fit the entire file into memory at once or do two passes over all data. Thus you can also encrypt files of many gigabytes.

usage

First, you need a keypair. To generate a new random keypair use the builtin keygenerator:

aenker kg -o ~/aenker.priv -p ~/aenker.pub

Send your public key aenker.pub to anyone who wants to encrypt data for you, keep your private key .. well, private. Note: aenker only performs anonymous Diffie-Hellman and the keys are not signed or certified. To protect against man-in-the-middle attacks you should transfer the key over a secure channel or verify the integrity on a second channel.

Encrypt a simple message using the public key:

echo 'Hello, World!' | aenker encrypt -p aenker.pub > message.ae

Decrypt it using the private key:

aenker decrypt -k aenker.priv < message.ae

You can specify input and output files with -i/-o and use the aliases seal/open which are commonly used with AEADs:

aenker seal -i documents.tar -o documents.tar.ae -p recipient.pub
aenker open -i documents.tar.ae -k mykey.sec | tar xf -

The key flags -p/--peer and -k/--key accept the base64-encoded keys on the commandline, too. This is not safe for various reasons, so avoid using it for your private key.

aenker seal -p lGLDUgFvp8TSwJ17VC9k0/T9mNWvfGoJ42zauMkAFBo=

advanced key generation

Generally, Curve25519 - and thus aenker - accepts any 32 byte value as a key. You could generate a private key by other means and then only calculate the public key to distribute it. You might just read from system randomness:

head -c32 /dev/urandom | base64 > privatekey
aenker keygen pubkey -k privatekey > publickey

You could use a single private key and pass the --symmetric flag when encrypting. This will derive the public key internally and proceed as usual but you will use the same key for decryption, which effectively turns this into a symmetric encryption.

Or you could pass --password and use a password-based key derivation function compatible with ansemjo/stdkdf:

stdkdf -salt aenker -cost hard | aenker kg pk > publickey
aenker seal -p publickey -i message -o message.ae
aenker open -i message.ae --password

Generate a password-based public key like above for distribution (both yield the same key):

aenker keygen --password --salt mysalt
stdkdf -salt mysalt -cost hard | curvekey pub

installation

install directly with go:

go get -u github.com/ansemjo/aenker

install from tarball / clone:

You can use the makefile to build a static binary and embed proper version information:

make aenker
sudo make install

install a package / release

Or download a release from GitHub.

documentation

All of the commands output a nicely formatted help message, so you can use --help at any time:

aenker encrypt --help

Furthermore, you can go to docs/aenker.md if you're looking at this online or install manpages with:

aenker docs man -d ~/.local/share/man/
man aenker-encrypt

autocompletion

Completion scripts for your shell can be generated and sourced with:

 . <(aenker docs completion)

Or install the script globally with:

aenker docs completion | sudo tee /usr/share/bash-completion/completions/aenker

file detection

Append this in your ~/.magic file:

0 string aenker\xe7\x9e aenker encrypted file
!:mime application/x-aenker

And file should detect encrypted files:

file message
message: aenker encrypted file
xxd message | head -2
00000000: 6165 6e6b 6572 e79e 42f7 5470 a191 973e  aenker..B.Tp...>
00000010: dd2e 86ab 501e 9eea 6819 7249 9169 4229  ....P...h.rI.iB)

disclaimer

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Please be advised that I am not a professional cryptographer. This is merely a hobby of mine which I hope can be useful to you.