gencrypt

Crates.iogencrypt
lib.rsgencrypt
version0.10.0
created_at2025-05-23 05:38:50.189576+00
updated_at2025-12-10 09:29:15.806425+00
descriptionPersonal usage hashing utility.
homepage
repository
max_upload_size
id1685916
size152,578
Ji Younghyun (younghyun1)

documentation

README

gencrypt

gencrypt is a tool for the paranoid used in encrypting, obfuscating, and compressing as well as decrypting arbitrary text or files using a password.

It combines:

  • Key derivation with PBKDF2-HMAC-SHA256 (600,000 iterations)
  • A custom byte-masking step
  • Compression with zstd
  • Authenticated encryption using AES‑256‑GCM
  • URL-safe, no-padding Base64 for transport

You can use it as:

  • A CLI application to encrypt/decrypt text and files

  • A Rust library to call encode_custom / decode_custom from your own code

Installation

From crates.io (recommended)

If you have a working Rust toolchain with Cargo installed:

cargo install gencrypt

This will download, build, and place the gencrypt binary in ~/.cargo/bin.
Make sure that directory is on your PATH.

Confirm installation:

gencrypt --help

From source

  1. Clone the repository:

    git clone https://github.com/<your-username>/gencrypt.git
    cd gencrypt
    
  2. Build in release mode:

    cargo build --release
    
  3. The compiled binary will be at:

    target/release/gencrypt
    

    You can run it directly or copy/symlink it somewhere on your PATH.

Using as a library

Add gencrypt as a dependency in Cargo.toml:

[dependencies]
gencrypt = "0.1"

Then, in your Rust code:

use gencrypt::crypto::{encode_custom, decode_custom};

fn main() -> Result<(), String> {
    let password = "correct horse battery staple";
    let plaintext = "Hello, world!";

    // Encrypt
    let ciphertext = encode_custom(plaintext, password);
    println!("Ciphertext: {ciphertext}");

    // Decrypt
    let recovered = decode_custom(&ciphertext, password)?;
    println!("Recovered: {recovered}");

    Ok(())
}

For binary-safe usage (arbitrary bytes instead of UTF‑8 strings), use the *_bytes APIs:

use gencrypt::crypto::{encode_custom_bytes, decode_custom_bytes};

fn roundtrip_bytes() -> Result<(), String> {
    let password = "secret";
    let data = b"\x00\xffbinary data\x01";

    let encoded = encode_custom_bytes(data, password);
    let decoded = decode_custom_bytes(&encoded, password)?;

    assert_eq!(decoded, data);
    Ok(())
}

How it works (high level)

The main logic lives in crypto.rs and is used by the UI code in main.rs.

Given an input and a password:

  1. A random salt and nonce are generated.
  2. derive_keys(password, salt) uses PBKDF2‑HMAC‑SHA256 to produce:
    • A small set of bytes for the custom masking step
    • A 32‑byte AES‑256 key
  3. The input bytes are masked with a rolling mix value for an extra obfuscation layer.
  4. The masked bytes are compressed with zstd (level 3).
  5. The compressed data is encrypted using AES‑256‑GCM with the derived key and random nonce.
  6. The result is: salt || nonce || ciphertext, encoded with URL-safe Base64 (no padding).

Decoding reverses these steps, verifying the AES‑GCM tag to ensure integrity and authenticity before attempting decompression or unmasking.

Building / Running Tests

To build (debug):

cargo build

To run tests:

cargo test

Security notes

  • The password is stretched with PBKDF2-HMAC-SHA256 using 600,000 iterations, which is intentionally slow to hinder brute-force attacks.
  • Encryption uses AES‑256‑GCM, providing confidentiality and integrity.
  • Nevertheless, do not treat this as a substitute for a fully reviewed, widely used cryptographic standard or protocol.
  • Always keep your passwords secret and avoid reusing them across different systems.

Use at your own risk and verify that it meets your security requirements before using it for sensitive data.

Commit count: 0

cargo fmt