Skip to content

adamierymenko/fenc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fenc: a utility to just fully encrypt a file

"Because sometimes you just want to fully encrypt a file."

I wrote this in a short bout of rage coding because I was working on some stuff on an air gapped machine and I just wanted to fully encrypt a file with a simple passphrase to safely store it in a repo for transfer back into dangerousland.

It turns out that fully encrypting a file from the command line is a remarkable pain. I had GPG, but I didn't want to encrypt to someone's public key with a bunch of RSA crap. I just wanted to fully encrypt a file with a simple passphrase. You can do this with GPG but the arguments are confusing. I used "--symmetric" and everything seemed okay but it turns out that by default this also generates a key that I don't want and also seems to encrypt to that key and WTF and I give up. It's also possible to with OpenSSH's command line utility but this is also confusing and when I go to decrypt it I'll probably have the key but I'll forget the exact command line arguments I used for OpenSSH so I'll never be able to recover my data.

All I wanted to do was to fully encrypt a file from the command line, so I broke down and wrote a C program to do it.

Usage

It's a tiny C program so just type make to build or:

cc -O -o fenc fenc.c

On windows you might need to remove -DHAS_PASSPHRASE from the Makefile. It does require 64-bit ints a few modern things like stdint.h, so it might not build on the VAX that was found sealed in a tomb with Pharaoh.

Using a key stored in a file:

fenc e file-with-key plaintext ciphertext
fenc d file-with-key
ciphertext plaintext

Using a key on the command line:

fenc e '!s00pers3kret' plaintext ciphertext
fenc d '!s00pers3kret' ciphertext plaintext

Entering a key on the terminal:

fenc e '+' plaintext ciphertext
key:
reenter key:
fenc d '+' ciphertext plaintext
key:

Piping:

cat /some/file | fenc e '!foo' >>bar cat bar | fenc d '!foo' >>baz

Warning: using a key on the command line is often unsafe since it might get saved to your history. If you do this symlink your history to /dev/null and be aware of what you are doing. But I won't stop you because I don't think you are an idiot.

YOLO installation instructions:

curl https://raw.githubusercontent.com/adamierymenko/fenc/master/fenc.c >>fenc.c ; cc -O2 -o fenc fenc.c ; rm -f fenc.c

FAQ

Why is encrypting and decrypting with a keyfile not working?

Try removing the newline from the end of the keyfile.

Why is this not building on Windows?

Try removing -DHAS_PASSPHRASE from the Makefile. This will remove passphrase functionality which needs unix specific libraries.

Internals

This program uses Daniel Bernstein's excellent Salsa20 encryption algorithm to just encrypt a file. It reads from an input file or STDIN and writes to an output file or STDOUT. It does not support any complicated advanced features because if I wanted that I would learn GPG's command line arguments.

The key is read from a file, from the command line or from the terminal (see security section below) and is then hashed by being self-encrypted with Salsa20. Then a random 64-bit IV is generated and is prepended to the output. At the end a checksum is encrypted and written so you can tell if you got the key right on decrypt.

For reading the key from the terminal it uses OpenBSD's readpassphrase() function, which will only be compiled in if it is available.

It's only 530 lines of C code and should compile on almost anything. It's missing code to generate a good random IV on Windows, so if someone wants to build it there they can do a pull request and add it. Right now it will work on Windows but will just use the clock. For the IV this is technically okay but it's better to use strong randomness for crypto stuff as a rule.

Security

Security is probably pretty good. It's tiny and simple so there's not a lot of bug surface area. It uses 256-bit keys and a well-regarded modern algorithm.

Using a simple checksum for authentication would be bad if this were a network protocol since it would make it vulnerable to oracle attacks, but this is just for simple one-off encryption of files. Brute force oracle attacks aren't practical here unless you're using it as part of some kind of interactive API that someone can hammer all day.

A 64-bit random IV is used to make the key stream unique, so technically it's okay to use the same key more than once for different files. This also means that encrypting the same data multiple times with the same key will yield different results, so if you see this it's a feature not a bug.

Warranty

None. This is for doing stuff like encrypting your AWS secrets to put them in a private repo, not for classified war plans or pics of dead aliens from Roswell.

License

2-clause BSD, so do whatever you want with it.