A secure file encryption utility, written in rust.

Last update: May 22, 2022

Dexios

What is it?

Dexios is a command-line file encryption utility, suitable for encrypting files before uploading them to a cloud-service. It is written entirely in rust and contains no unsafe code (some dependencies may contain unsafe code, but they have received the correct audits and are deemed secure).

It uses AES-256-GCM encryption with argon2id to generate the encryption key.

It has been tested on Void Linux, but more platforms will be tested in the future.

For securely erasing the file, it's about as good as we will get. It doesn't factor in how the host OS handles things, or the filesystems. It overwrites the file with many random bytes, and then with zeros, before truncating it and "removing" it with the OS.

Building notes

As mentioned in the AES-GCM crate docs, please enable certain flags while building. For example:

RUSTFLAGS="-Ctarget-cpu=native -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"

Change native to whichever CPU family/model you are going to be running the code on, if it's going to be ran on a different machine.

Checksums

Hashing mode uses Blake3 for verification, due to it's speed, security and regular updates. (very ideal for this use case).

This was originally sha3-512 in versions 3.x.x and below, and was KangarooTwelve in 4.x.x (via the tiny_keccak crate) but since v5 it has been changed to Blake3 for a number of reasons.

The tiny_keccak crate hasn't received updates in a long while, and is no longer actively maintained.

The k12 crate is ideal for this situation - but it is rather immature compared to some other hashing implementations, so Blake3 will be our main hashing algorithm, and there are no plans to change this as of yet.

Blake3 also offered some marginal performance benefits, but this could be due to a number of factors.

Performance

Tests were ran on a system with a Ryzen 7 3700x and 16gb of 3000MHz RAM - running Void Linux. The file used was originally 3.5GiB, and it was stored on a Cruicial MX500 SSD.

Version 6 removed JSON entirely, and dropped base64, which really shows in the performance metrics.

The time was determined via /usr/bin/time -f "%e"

Version -esyk -dsyk
3.2.8 44.37s 40.91s
4.0.0 23.70s 30.43s
5.0.0 22.48s 28.66s
5.0.2 20.14s 21.26s
5.0.9 19.31s 18.92s
6.0.0 11.74s 11.59s

Output file sizes

In versions 5.x.x and below, the 3.5GiB test file was encrypted at 4.72GiB - this involved a lot of overhead for base64 and a tiny amount with the JSON.

As of version 6, JSON and base64 has been dropped entirely. This has reduced the file size down to be marginally higher than our 3.5GiB test file (284 bytes higher, to be exact).

Environment Variables

Dexios can read your key from an environment variable! Just set DEXIOS_KEY and it will automatically be detected and used. Due to using different salts and nonces for every encryption, there is no inherent risk in reusing keys - although it's not a good security practice.

Key Inputs

The priority is as follows:

  1. First, Dexios will check for whether or not you have specified a keyfile (via -k or --keyfile)
  2. If no keyfile is detected, it will look for the DEXIOS_KEY environment variable
  3. If neither of the above are found, you will be shown a prompt to enter a password manually

Usage Examples

To encrypt a file, and show the hash of the encrypted (output) file for verification later on:

dexios -es test.txt test.enc

To decrypt a file, and show the hash of the encrypted file beforehand (to compare with the hash generated above):

dexios -ds test.enc test.txt

To encrypt a file, and erase the original file:

dexios -e --erase test.txt test.enc

To use a keyfile for encryption:

dexios -ek keyfile test.txt test.enc

To encrypt all .mp4 files in a directory, we can use find. This works a LOT better with a keyfile/environment variable key as you will have to input the password manually each time otherwise. It will append .enc to the end of your files. You can remove -maxdepth 1 to make this run recursively.

find *.mp4 -type f -maxdepth 1 -exec dexios -esyk keyfile {} {}.enc \;

To encrypt all .mp4 files in a directory, and remove the original files once encrypted:

find *.mp4 -type f -maxdepth 1 -exec dexios -esy --erase -k keyfile {} {}.enc \;

To Do

  • Error handling
  • Ensure the encryption and decryption functions are air-tight
  • Add a secure-erase function for the input/source file
  • Run some more tests, specifically on large files
  • Test keyfile functionality
  • Don't show stdin text when entering password inside of the terminal
  • Add checks for output files so we don't overwrite any by mistake
  • Hash the file before encryption and after decryption, so the user can confirm the data is exactly the same
  • Use clap subcommands instead of arguments to make it easier to use
  • Optimise reading the input/output files, so less disk usage
    • Find a way to encrypt large files (larger than the system's memory) - this is just another optimisation though
    • Optimise memory usage in general too
  • Further optimise the reading and handling of the data, especially in memory.
    • Larger files in hashing mode will cause dexios to force quit, due to absurdly high memory usage. This is because the data is being copied in memory multiple times, instead of re-using the same buffer. I believe this needs a Cursor to resolve, and a patch will be released once I have found the best solution.
  • Refactor/split everything into semi-specialised files, to make the codebase more maintainable
  • Add benchmarking switch that doesn't write to the disk
  • Manually zeroize sensitive data in RAM

GitHub

https://github.com/brxken128/dexios
Comments
  • 1. File is created in filesystem while using the -b benchmark flag [BUG]

    File is created in filesystem while using the -b benchmark flag When using an input file larger than memory mode limit a 0kb is created in the filesystem.

    To reproduce Command to reproduce this behaviour: In empty folder create testfile then dd bs=10M seek=1 of=testdata count=0 ./dexios -eb testdata out

    Should be a very simple fix

    Reviewed by Rust-Galt at 2022-05-23 07:14
  • 2. Added enums for Parameter struct - not fully tested for logic errors!

    I'm new to Rust and found this project interesting as I wanted to create something like this myself! Added enums for more descriptive Parameter struct! And implementatons. Did not test for logic errors!

    Reviewed by Rust-Galt at 2022-05-22 19:27
  • 3. [BUG] standalone hashing producing different hashes in stream and memory modes

    Describe the bug Using Dexios built from the standalone-hash branch will produce two different hashes, based on whether you're using stream or memory hashing.

    To Reproduce Command to reproduce this behaviour: dexios hash test.txt dexios hash -m test.txt

    Expected behavior Hashes should be equal (I believe - maybe this is intentional from the BLAKE3 team with regards to hasher.update() and blake3::hash)

    Desktop (please complete the following information):

    • OS: Void Linux

    Maybe this is intentional - if so, I'd advise users to just let Dexios handle which modes to use. hash-standalone implements file-size checking, just as encrypt.rs and decrypt.rs do.

    Reviewed by brxken128 at 2022-05-21 17:48
  • 4. [BUG] Decrypt on the chacha branch not working

    Describe the bug Decrypting a file using Dexios built from the chacha branch does not work.

    The nonce and salt are both saved and read correctly (confirmed with a hex editor).

    This issue happens with both the default XChaCha20-Poly1305 and the -g for AES-256-GCM switch.

    This is the only issue I have found so far with the implementation (aside from implementing it idiomatically, but that's sorted now).

    To Reproduce Command to reproduce this behaviour: ./dexios encrypt -yk keyfile test.raw test.enc and then ./dexios decrypt -yk keyfile test.enc test.raw

    Expected behavior It should decrypt the file, instead it returns an error.

    Desktop:

    • OS: Void Linux (GNU's libc)
    Reviewed by brxken128 at 2022-05-20 22:34
  • 5. Implement Standalone Hashing Mode

    This allows for the command dexios hash test.txt

    It can use memory or stream mode, and implements the same checking that encrypt.rs and decrypt.rs implement to automatically detect whether or not the file should be hashed in memory or stream mode.

    There are optional -s and -m switches, but -s will redirect you to memory mode if your file isn't large enough.

    Reviewed by brxken128 at 2022-05-21 19:01
  • 6. Stream Encryption

    This branch adds fully functioning stream encryption/decryption, with appropriate switches to use it.

    I believe it's slower than normal modes, so it will not become the default. It also has no support for blake3, and is not interchangeable with normal modes (due to how the nonce is 8 bytes+a 32 bit counter as opposed to 12 static bytes).

    Reviewed by brxken128 at 2022-05-13 14:11
  • 7. [BUG] Not following SemVer

    I have just realised that Dexios has not been adhering fully to the semantic versioning guidelines.

    I've mistakenly forgotten to reset the patch version every time the minor version has been incremented - this will change when 7.5.0 is released (this update should include tar or zip functionality).

    My apologies for any inconvenience.

    Reviewed by brxken128 at 2022-05-23 08:32
  • 8. [FEATURE] Encrypting a Directory

    I personally do not plan to add support for encrypting/decrypting based on a glob pattern (at this moment in time anyway). I've tried before and could not get a user-friendly implementation going.

    What I do think could be valuable is encrypting a singular directory. My plan was to encrypt each file in the directory as normal (so they each have their own salt/nonce), and then to compress them into a tar or zip file. I'm leaning more towards tar.

    Then, that compressed file will be encrypted once again, this time with ideally a different key provided by the user, or the same key could work but only with a different salt.

    If the keys were different, a brute force attack would take considerably longer. With the same key and different salts (this is the default implementation in Dexios anyway), an attacker just has to find one key and all of the files will be decrypted. I guess functionality should be added for both use cases.

    As far as I'm aware, there are no cryptographic downfalls to encrypting twice with different nonces in this case. That, and the compression imposed by taring the files should be more than enough, although I'd definitely inspect output files before releasing this feature.

    I would suggest file-name encryption also, but if the whole tar file is encrypted anyway, I don't see the point.

    You may track the progress of this on the directory-encrypt branch - I plan to work heavily on this feature and I don't see it taking more than 2/3 days - most of the groundwork has been laid out.

    Appropriate GA tests will be added also.

    Reviewed by brxken128 at 2022-05-22 20:13
Related tags
A Rust binary for file encryption to multiple participants.

Kaspa-miner A Rust binary for file encryption to multiple participants. Installation From Sources With Rust's package manager cargo, you can install k

Apr 29, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

May 19, 2022
rabe is an Attribute Based Encryption library, written in Rust

Rabe rabe is a rust library implementing several Attribute Based Encryption (ABE) schemes using a modified version of the bn library of zcash (type-3

Apr 10, 2022
A Rust library for lattice-based additive homomorphic encryption.

Cupcake Cupcake is an efficient Rust library for the (additive version of) Fan-Vercauteren homomorphic encryption scheme, offering capabilities to enc

May 17, 2022
A Rust Library of China's Standards of Encryption Algorithms (SM2/3/4)

Libsm Libsm is an open source pure rust library of China Cryptographic Algorithm Standards. It is completed by a collaborative effort between the Cryp

May 16, 2022
In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

Apr 13, 2022
WebAssembly wrapper of the rage encryption library

rage-wasm: WebAssembly wrapper of rage rage is a simple, modern, and secure file encryption tool, using the age format. It features small explicit key

Apr 17, 2022
End-to-end encryption and mutual authentication for distributed applications.
End-to-end encryption and mutual authentication for distributed applications.

✨ Hands-on Introduction: Build end-to-end encrypted, mutually-authenticated, secure messaging in Rust ✨ Rust and Elixir libraries for end-to-end encry

May 15, 2022
Meta-repository for Miscreant: misuse-resistant symmetric encryption library with AES-SIV (RFC 5297) and AES-PMAC-SIV support

The best crypto you've never heard of, brought to you by Phil Rogaway A misuse resistant symmetric encryption library designed to support authenticate

Apr 29, 2022
Secure storage for cryptographic secrets in Rust

secrets secrets is a library to help Rust programmers safely held cryptographic secrets in memory. It is mostly an ergonomic wrapper around the memory

May 12, 2022
A secure development tool box and fintech application made with Rust to be used for developing cryptocurrencies on the blockchain.

Crypto Fintech Tools for Rust (CFT) Dependencies Rust MacOS Homebrew # xcode cli tools xcode-select --install # install dependencies using Homebrew b

Apr 15, 2022
A safe implementation of the secure remote password authentication and key-exchange protocol (SRP), SRP6a and legacy are as features available.

Secure Remote Password (SRP 6 / 6a) A safe implementation of the secure remote password authentication and key-exchange protocol (SRP version 6a). Ver

May 6, 2022
Use Touch ID / Secure Enclave for SSH Authentication!
Use Touch ID / Secure Enclave for SSH Authentication!

SeKey About SeKey is a SSH Agent that allow users to authenticate to UNIX/Linux SSH servers using the Secure Enclave How it Works? The Secure Enclave

May 15, 2022
A fast and secure multi protocol honeypot.

Medusa A fast and secure multi protocol honeypot that can mimic realistic devices running ssh, telnet, http, https or any other tcp and udp servers. W

May 16, 2022
Cross-platform Secure TUI Secret Locker
Cross-platform Secure TUI Secret Locker

SafeCloset keeps your secrets in password protected files. SafeCloset is designed to be convenient and avoid common weaknesses like external editing o

May 6, 2022
A Secure Capability-Based Runtime for JavaScript Based on Deno
A Secure Capability-Based Runtime for JavaScript Based on Deno

Secure Runtime secure-runtime, as the name implies, is a secure runtime for JavaScript, designed for the multi-tenant serverless environment. It is an

Feb 7, 2022
Web-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.
Web-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.

Building 1. Install rustc, cargo and rustfmt. $ curl https://sh.rustup.rs -sSf | sh $ source $HOME/.cargo/env $ rustup component add rustfmt When buil

May 21, 2022
Scrypto Advent Calendar. Learn the new programming langage to build quick and secure DeFi applications.

Scrypto Advent Calendar I am publishing new Christmas related Scrypto examples every day from Dec 1st to Dec 25th. "Watch" this project to get notifie

May 9, 2022
Simplified, secure privledge escalation

doit.rs A simplified privledge escalation tool. Attempting to combine the memory safety guarantees of Rust with a small, auditable codebase. I was rea

Jan 6, 2022