Giter Club home page Giter Club logo

enchive's Introduction

Enchive : encrypted personal archives

Enchive is a tool to encrypt files to yourself for long-term archival. It's a focused, simple alternative to more complex solutions such as GnuPG or encrypted filesystems. Enchive has no external dependencies and is trivial to build for local use. Portability is emphasized over performance.

Supported platforms: Linux, BSD, macOS, Windows

The name is a portmanteau of "encrypt" and "archive," pronounced en'kīv.

Files are secured with ChaCha20, Curve25519, and HMAC-SHA256.

Manual page: enchive(1)

Installation

Clone this repository, then:

$ make PREFIX=/usr install

This will install both the compiled binary and manual page under PREFIX. For staged installs, DESTDIR is also supported. The binary doesn't have any external dependencies and doesn't actually need to be installed before use.

Usage

There are only three commands to worry about: keygen, archive, and extract. The very first thing to do is generate a master keypair using keygen. You will be prompted for the passphrase to protect the secret key, just like ssh-keygen.

$ enchive keygen

By default, this will create two files in $XDG_CONFIG_HOME/enchive (or $HOME/.config/enchive): enchive.pub (public key) and enchive.sec (secret key). On Windows, these are found under %APPDATA%\enchive instead. Distribute enchive.pub to any machines where you plan to archive files. It's sufficient to encrypt files, but not to decrypt them.

To archive a file for storage:

$ enchive archive sensitive.zip

This will encrypt sensitive.zip as sensitive.zip.enchive (leaving the original in place). You can safely archive this wherever.

To extract the file on a machine with enchive.sec, use extract. It will prompt for the passphrase you entered during key generation.

$ enchive extract sensitive.zip.enchive

The original sensitive.zip will be reproduced.

With no filenames, archive and extract operate on standard input and output.

Key management

One of the core features of Enchive is the ability to derive an asymmetric key pair from a passphrase. This means you can store your archive key in your brain! To access this feature, use the --derive (-d) option with the keygen command.

$ enchive keygen --derive

There's an optional argument to --derive that controls the number of key derivation iterations (e.g. --derive=26). The default is 29. This is a power two exponent, so every increment doubles the cost both in memory and computational demands.

If you want to change your protection passphrase, use the --edit option with keygen. It will load the secret key as if it were going to "extract" an archive, then write it back out with the new options. This mode will also regenerate the public key file whether or not it exists.

Enchive has a built-in protection key agent that keeps the protection key in memory for a configurable period of time (default: 15 minutes) after a protection passphrase has been read. This allows many files to be decrypted inside a brief window with only a single passphrase prompt. Use the --agent (-a) global option to enable it. If it's enabled by default, use --no-agent to turn it off.

$ enchive --agent extract file.enchive

Unlike gpg-agent and ssh-agent, this agent need not be started ahead of time. It is started on demand, shuts down on timeout, and does not coordinate with environment variables. One agent is created per unique secret key file. This feature requires a unix-like system.

Notes

The major version number increments each time any of the file formats change, including the key derivation algorithm.

There's no effort at error recovery. It bails out on early on the first error. It should clean up any incomplete files when it does so.

A purposeful design choice is that encrypted/archived files have no distinguishing marks whatsoever (magic numbers, etc.), making them indistinguishable from random data.

Frequently asked questions

This tool will never achieve critical mass, so what's the point?

Enchive doesn't need to interact with any other systems or people, so there's no need for critical mass, nor that there are any other users.

Why can't you use an existing/established tool instead?

I'm not aware of any tool that does everything Enchive does. GnuPG comes close, but doesn't support deriving a key pair from a passphrase. If you're aware of an equal or better tool, please let me know.

Isn't it dangerous to derive a key pair from a passphrase?

It is when it's done incorrectly. However, Enchive uses a memory-hard key derivation scheme that makes cracking passphrases very expensive — prohibitively so for any decent passphrase. This is because anyone who has access to even a single encrypted file can mount an offline attack.

Deriving asymmetric keys from a passphrase is a standard practice in the Bitcoin world: brainwallets. The caveat is that the passphrase must be sufficiently long, preferably chosen by a computer or with dice.

When generating a master key, Enchive's default configuration is extremely paranoid. It would be far cheaper to break into your home and perform an evil maid attack than it would be to crack even a short passphrase. This is not the weak point.

Shouldn't the initialization vector (IV) be generated randomly?

The purpose of an IV is to allow the same key to be safely used multiple times. This is particularly important when the same key is derived on different occasions by Diffie-Hellman between the same key pair. Enchive generates a random ephemeral key pair each time a file is encrypted, so the IV is unnecessary.

Since ChaCha20 requires an IV regardless, Enchive simply uses the hash of the key. This has the additional effect of allowing the client to verify its symmetric key before beginning decryption. Otherwise a wrong key would only be detected by the MAC after decryption has completed.

I'm getting the error "Value too large for defined data type."

This is a flaw in the 32-bit version of glibc that prevents C programs from even opening files larger than 2GB. Compile with "large file support" enabled:

make CFLAGS='-O3 -D_FILE_OFFSET_BITS=64'

Alternatively, use your shell to open files for Enchive:

$ enchive archive <largefile >largefile.enchive

Note that Enchive will not be able to delete shell-opened files in case of errors (tampering, etc.).

Encryption/decryption algorithm

The process for encrypting a file:

  1. Generate an ephemeral 256-bit Curve25519 key pair.
  2. Perform a Curve25519 Diffie-Hellman key exchange with the master key to produce a shared secret.
  3. SHA-256 hash the shared secret to generate a 64-bit IV.
  4. Add the format number to the first byte of the IV.
  5. Initialize ChaCha20 with the shared secret as the key.
  6. Write the 8-byte IV.
  7. Write the 32-byte ephemeral public key.
  8. Encrypt the file with ChaCha20 and write the ciphertext.
  9. Write HMAC(key, plaintext).

The process for decrypting a file:

  1. Read the 8-byte ChaCha20 IV.
  2. Read the 32-byte ephemeral public key.
  3. Perform a Curve25519 Diffie-Hellman key exchange with the ephemeral public key.
  4. Validate the IV against the shared secret hash and format version.
  5. Initialize ChaCha20 with the shared secret as the key.
  6. Decrypt the ciphertext using ChaCha20.
  7. Verify HMAC(key, plaintext).

Key derivation algorithm

Enchive uses an scrypt-like algorithm for key derivation, requiring a large buffer of random access memory. Derivation is controlled by a single difficulty exponent D. Secret key derivation requires 512MB of memory (D=29) by default, and protection key derivation requires 32MB by default (D=25). The salt for the secret key is all zeros.

  1. Allocate a (1 << D) + 32 byte buffer, M.
  2. Compute HMAC_SHA256(salt, passphrase) and write this 32-byte result to the beginning of M.
  3. For each uninitialized 32-byte chunk in M, compute the SHA-256 hash of the previous 32-byte chunk.
  4. Initialize a byte pointer P to the last 32-byte chunk of M.
  5. Compute the SHA-256 hash, H, of the 32 bytes at P.
  6. Overwrite the memory at P with H.
  7. Take the first D bits of H and use this value to set a new P pointing into M.
  8. Repeat from step 5 1 << (D - 5) times.
  9. P points to the result.

Compilation

To build on any unix-like system, run make. The resulting binary has no dependencies or external data, so you can just copy/move this into your PATH.

$ make

The easiest way to build with Visual Studio is to use the amalgamation build. On any unix-like system (requires sed):

$ make amalgamation

This will create enchive-cli.c, a standalone C program that you can copy anywhere and compile. Over on Windows:

C:\> cl.exe -nologo -Ox enchive-cli.c advapi32.lib

The compile-time options below also apply to this amalgamation build.

Compile-time configuration

Various options and defaults can be configured at compile time using C defines (-D...).

ENCHIVE_OPTION_AGENT

Whether to expose the --agent and --no-agent option. This option is 0 by default on Windows since agents are unsupported.

ENCHIVE_AGENT_TIMEOUT

The default agent timeout in seconds. This can be configured at run time with an optional argument to --agent.

ENCHIVE_AGENT_DEFAULT_ENABLED

Whether or not to enable the agent by default. This can be explicitly overridden at run time with --agent and --no-agent.

ENCHIVE_PINENTRY_DEFAULT

The default program to use for pinentry.

ENCHIVE_PINENTRY_DEFAULT_ENABLED

Whether or not to use pinentry by default when reading passphrases.

ENCHIVE_FILE_EXTENSION

The file extension to add when archiving and remove when extracting. The default is .enchive, as it appears in the examples.

ENCHIVE_KEY_DERIVE_ITERATIONS

Power-of-two exponent for protection key derivation. Can be configured at run time with --iterations.

ENCHIVE_SECKEY_DERIVE_ITERATIONS

Power-of-two exponent for secret key derivation. Can be configured at run time with the optional argument to --derive.

ENCHIVE_PASSPHRASE_MAX

Maximum passphrase size in bytes, including null terminator.

enchive's People

Contributors

degaart avatar drdcd avatar extrowerk avatar ilohmar avatar jung-kurt avatar markusboehme avatar skeeto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

enchive's Issues

Being added to nixpkgs

Hi, I wanted to let you know that I'm asking for enchive to be added to the nixpkgs repository. nixpkgs is the pkg collection of the nix package manager.

You can find the pull request here

Thanks for this wonderful piece of software

feature: AES NI

My idea was to develop kewlfft/dse to bring some new features and I found your project. I may rather fork this one then because you have already done a very good job.
The only thing maybe is that it is not natural to me to call archive and extract, ciphering and deciphering in the command line but I will probably get used to it.

One improvement I had in mind for my project was to add AES NI to improve speed, is it something you have ever considered for yours or are you fully satisfied with ChaCha20?

Add warning about safety in README

It's usually a good idea for young/experimental/unaudited crypto code to add a warning somewhere for people to be aware that the tool might not be right for use in security-critical situations.

execution speed on openbsd 7.3

enchive on openbsd 7.3 runs ~5 times slower than on macos 10.13 or void linux.

Extraction of the same archive file takes 11.5 sec on openbsd and less than 2 seconds on macos:

On openbsd:

$ time ./enchive -s ~/.keep/keep.s extract < ~/.keep/.keep.enc > /dev/null
passphrase:
0m18.62s real 0m11.46s user 0m00.10s system

On macos:

$ time ./enchive -s ~/.keep/keep.s extract < ~/.keep/.keep.enc > /dev/null
passphrase:

real 0m7.87s
user 0m1.59s
sys 0m0.02s

Could the slowdown be caused by openbsd libc?

First 32 secret key bytes are always same

Does it make sense to store the first 32 bytes of the secret key since they seem to be always the same?

$ cat ~/.config/enchive/enchive.sec | xxd
00000000: 0000 0000 0000 0000 0003 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: a8e6 ea13 c621 1381 1be1 f0b9 a88f 3989  .....!........9.
00000030: 2dd3 0613 0535 16fb dffa ce61 cf2d 9977  -....5.....a.-.w

round filesize up

I think you can calculate the exact size of a file based on the encrypted version. This could leak information in some situations. Could be solved by rounding up to a 1MB boundary.

enchive-mode: load files in the right mode

Hi, I can load and save enchived files using enchive-mode, but they are all loaded in fundamental.
Is it possible to tell emacs to open them in the right mode?

Thanks, nicolò

Detected memory leak during archive and extract operations

I compiled enchive with clang and the -fsanitize=address flag.

./enchive archive filename

==7853==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 34 byte(s) in 1 object(s) allocated from:
    #0 0x4a054b in __interceptor_malloc (/root/enchive/enchive+0x4a054b)
    #1 0x4c9221 in storage_directory /root/enchive/src/enchive.c:268:16
    #2 0x7fc663bc4b44 in __libc_start_main /build/glibc-qK83Be/glibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: 34 byte(s) leaked in 1 allocation(s).

./enchive extract filename

==7867==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 34 byte(s) in 1 object(s) allocated from:
    #0 0x4a054b in __interceptor_malloc (/root/enchive/enchive+0x4a054b)
    #1 0x4c9221 in storage_directory /root/enchive/src/enchive.c:268:16
    #2 0x7fbd7d399b44 in __libc_start_main /build/glibc-qK83Be/glibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: 34 byte(s) leaked in 1 allocation(s).

Emacs interface(a la epg)?

It would be really useful if I could open up an encrypted file in Emacs, upon which I'd be prompted for a password. Then, when I'm done editing the file, the emacs interface would encrypt the file and close the buffer.

Encrypt-then-MAC

MAC-then-Encrypt has resulted in serious problems in other tools and protocols. It intuitively makes sense why that would be. You're willingly allowing data to be tampered with and for that tampering to go unnoticed. That's a serious problem. Why risk that at all if you could choose to not take such an unnecessary risk?

Reopened from: #19

enchive won't archive big files

Hi, I have a 3.5Gb video file.

enchive archive BigFile.mp4

enchive: could not open input file -- BigFile.mp4

I have not tried with other files that big, but sure up to 600Mb works. I don't think there are problems in accessing the file since I was able to check the sha1 hash. There is enough hard disk space and there not exist a file named BigFile.mp4.enchive. The only doubt I have is if it's limited by the RAM, but I have 13Gb swap so in theory it should work anyway

Feature request: secure delete

After successfully archiving a plaintext file, it would be desirable if the --delete option securely obscured the input file before unlinking it. This could be with a configured program such as shred (something like --sdelete[=program]?) or perhaps it could be done natively with routines that enchive already uses. Even simply overwriting the input file with the output file would have some value.

global buffer overflow

I compiled enchive with clang version 7.0.0 (trunk 335864) and -fsanitize=address on Debian 9 x64 and upon running ./enchive keygen was greeted with this error:

==19429==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000052e5f0 at pc 0x000000432949 bp 0x7ffca52e7130 sp 0x7ffca52e68b0
READ of size 1 at 0x00000052e5f0 thread T0
    #0 0x432948 in strncmp /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:463:3
    #1 0x4fdc2c in parse_command /root/enchive/src/enchive.c:1134:13
    #2 0x4fdc2c in main /root/enchive/src/enchive.c:1591
    #3 0x7f4cfd81f2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
    #4 0x41d8a9 in _start (/root/enchive/enchive+0x41d8a9)

0x00000052e5f0 is located 48 bytes to the left of global variable 'keygen' defined in 'src/enchive.c:1146:39' (0x52e620) of size 128
0x00000052e5f0 is located 0 bytes to the right of global variable 'command_names' defined in 'src/enchive.c:1120:19' (0x52e5c0) of size 48
SUMMARY: AddressSanitizer: global-buffer-overflow /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:463:3 in strncmp

Arguments missing on help

It seems the --derive or -d argument is missing from the help (under macOS I could not find it). Could it be added? Is there any other missing? Thanks!

extract to stdout

It would be very nice to have a way to extract files to stdout. I just want to display the contents of a file without actually extracting the file to disk. This would be useful in cases where I used to use gpg to store a passphrase for a program like offlineimap for example.

Why is inserted Emacs' buffer read-only, and should it be?

I just tested this with emacs -q: Loading and enabling enchive-mode, then opening an ".enchive" file, the created buffer is read-only.

I am unsure as to whether it should be, but my main issue is: how come? I read quite some docs, did my googling, experimented with enchive-mode-hook and modifying the handler code directly, and I can't seem to figure out when/why the buffer gets buffer-read-only t. Also, I seem to recall that the behavior changed at some point, but unfortunately, I have no idea at what point (new Emacs build, new enchive-mode, or something else).

Any insights appreciated!

The enchive default extension is a distinguishing mark

I find the default enchive extension a strong distinguishing mark that seems in contradiction with the design of the tool:

A purposeful design choice is that encrypted/archived files have no distinguishing marks whatsoever (magic numbers, etc.), making them indistinguishable from random data.

Using something shorter and more generic like .enc or .arc would make it more neutral, otherwise I see it as a flashing light that makes enchive files very recognizable and therefore more prone to targeted attacks.

This is to have your opinion on the topic as you may see it differently.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.