Skip to content

Latest commit

 

History

History
63 lines (40 loc) · 3.98 KB

File metadata and controls

63 lines (40 loc) · 3.98 KB

About DenCrypter

Origins and Evolution

This program was originally an exercise in which I learned to use Python's cryptography library. However, it started to lose the shape of an exercise as I watched the number of lines of code grow past what I was accustomed to for practice problems. I made the decision to turn this into a fully fledged CLI tool as a result.

I originally worked on a single file named dencrypter.py, still visible in the commit history. It was a rough outline of the program's features and logic, which changed in the following ways over time:

  • Originally supported AES-GCM (with 128-, 192-, and 256-bit keys)
  • Added ChaCha20 support, but eventually changed it to ChaCha20-Poly1305 after learning that the former is unauthenticated, and thus does not provide integrity
  • Split dencrypter.py into multiple modules (listed in src/dencrypter) after realising the project grew beyond single-file scope; this provided better separation of concerns and made testing simpler
  • Finished the program's logic
  • Packaged the project with pyproject.toml
  • Added tests and tweaked the program's logic as I discovered unhandled edge cases

What DenCrypter does

DenCrypter is a tool capable of randomly generating encryption keys of 16, 24 and 32 bytes, as well as encrypting or decrypting files with them, using AES-GCM and ChaCha20-Poly1305 ciphers. Keys are user managed.

Cryptography

DenCrypter leverages the running Operating System's CSPRNG to randomly generate keys through secrets.token_bytes(). This removes the need for Key Derivation Functions (KDF), since there is no low-entropy input to strengthen.

DenCrypter uses Authenticated Encryption with Associated Data (AEAD) ciphers, ensuring confidentiality and integrity with just one primitive:

  • AES ciphers use Galois Counter Mode (GCM)
  • ChaCha20 uses Poly1305 as Message Authentication Code (MAC)

This way, ciphertext and associated data are bound into a single authentication tag.

Nonces of 12 bytes are generated per-encryption through secrets.token_bytes(), where the 12-byte length is standard for both ciphers.

File format

All encrypted files have an 8-byte header made up of:

  • ENCR magic (4 bytes)
  • version (1 byte)
  • cipher_id (1 byte)
  • reserved (2 bytes)

The full header is passed as the associated data during encryption/decryption. This way, the authentication tag is computed over both the ciphertext and the header, and tampering attempts result in failure during decryption.

These measures protect against cipher substitution attacks, as well as format tampering.

Safety-oriented UX decisions

  • DenCrypter keys have .key extension. Encrypted files have .enc extension. The program refuses to work with keys and encrypted files that do not possess these extensions.
  • The --force parameter only applies to encryption and decryption, not for key generation; this is because overwriting a key file could cause permanent loss of data encrypted with it. Users must manually delete and regenerate a .key file if they wish to replace a key.

Scope and limitations

  • DenCrypter is NOT AUDITED and should NEVER be used in production systems!
  • DenCrypter does not currently support key derivation from passphrases, which makes using the tool inconvenient for users who wish to memorise a secret instead of managing key files
  • DenCrypter does not offer key management features; the user has the sole responsibility of managing their keys to prevent corruption or loss, and safeguard their encrypted files
  • DenCrypter does not currently support streaming/chunking for large files, which places the burden of chunking on the user if the file size exceeds available memory
  • DenCrypter does not support multi-recipient encryption; sending the same file to multiple users requires generating one key per recipient

Possible future additions

  • Passphrase mode, e.g. using Argon2id
  • Streaming/chunking mode for large files
  • Additional ciphers