A C++ library and CLI tool to encrypt/decrypt a file or folder using 7‑Zip for archiving and a chain of transform algorithms (default: AES then XOR).
Each encrypted file embeds a cleartext header with a Key ID (KID) so the correct key can be located in keys.txt without relying on line order.
- Zip with password (7‑Zip): The input file/folder is archived with
7zusing the provided password. - Transform chain: On encrypt, algorithms run in order (e.g., AES → XOR). On decrypt, algorithms run in the reverse order (XOR → AES).
- Clear header: The encrypted output begins with:
ENCLIBv1 KID:<64‑hex of SHA‑256(key)> <encrypted payload bytes...> - Key lookup by KID: The decryptor reads KID from the header, finds the matching key in
keys.txtby hashing each line (after trimming), then runs the reverse chain.
Key consumption policy (as you requested):
After a successful encrypt, the used key is removed fromkeys.txt(one‑time use). When testing on the same machine, use a separate copy of the keys file for decrypt, or switch the policy to consume only on decrypt.
- 7‑Zip CLI for password‑protected archives
- Pluggable transform chain (extensible). Defaults included:
- AES (OpenSSL EVP, demo settings)
- XOR (self‑inverse; demo only)
- KID‑based lookup: key order/position in
keys.txtdoesn’t matter - Duplicate key removal by KID when loading the keys file
- C++17 (e.g.,
g++) - OpenSSL for AES (
-lcrypto) - 7‑Zip:
7zmust be available in your PATH- Linux/WSL:
sudo apt install p7zip-full - macOS (Homebrew):
brew install p7zip - Windows: install 7‑Zip and add
7z.exeto PATH
- Linux/WSL:
Encryptor.h— API/types for the libraryEncryptor.cpp— encryption/decryption, header/KID, 7‑Zip calls, AES/XORmain.cpp— command‑line interface (CLI)
g++ -std=c++17 -O2 -o encrypt_demo main.cpp Encryptor.cpp -lcryptog++ -std=c++17 -O2 -o encrypt_demo.exe main.cpp Encryptor.cpp -lcryptoFor MSVC, link OpenSSL as installed on your system.
./encrypt_demo --help./encrypt_demo -e -i <inputPath> -o <encryptedFile> -k <keys.txt> [-p <zipPassword>]-i: input file/folder to zip-o: output encrypted file (e.g.,encrypted.dat)-k: path to the keys file-p: 7‑Zip archive password (default:zipSecret)
./encrypt_demo -d -i <encryptedFile> -o <outputDir> -k <keys.txt> [-p <zipPassword>]-i: the encrypted file (output of Encrypt)-o: target directory for extraction
# Encrypt
./encrypt_demo -e -i ./example.txt -o ./encrypted.dat -k ./keys_sender.txt -p zipSecret
# Decrypt
./encrypt_demo -d -i ./encrypted.dat -o ./decrypted_output -k ./keys_receiver.txt -p zipSecretIf your policy consumes the key on encrypt, use a separate copy of the keys file for decrypt during round‑trip tests on one machine.
- One key per line (UTF‑8, no BOM, no leading/trailing spaces).
- KID = SHA‑256(key) (64‑hex) is stored in the encrypted file header.
- The library de‑duplicates keys by KID when loading.
for i in {1..200}; do LC_ALL=C tr -dc 'A-Za-z0-9_-.' </dev/urandom | head -c 64; echo; done > keys_raw.txt
python3 - <<'PY'
import hashlib
seen=set(); out=[]
for k in open("keys_raw.txt","r",encoding="utf-8",errors="ignore"):
k=k.strip()
if not k: continue
kid=hashlib.sha256(k.encode()).hexdigest()
if kid in seen: continue
seen.add(kid); out.append(k)
open("keys.txt","w").write("\n".join(out)+"\n")
print("written",len(out),"keys to keys.txt")
PY- XOR is for demo only—do not rely on it for real confidentiality.
- The sample AES uses AES‑256‑CBC with a zero IV for simplicity. For real‑world use:
- Generate a random IV per file and store it in the header (e.g.,
IV:<hex>). - Consider AES‑GCM (confidentiality + integrity).
- Generate a random IV per file and store it in the header (e.g.,
- Protect your keys (
chmod 600 keys.txt, encrypted backups, etc.).
No matching key for KID=...- The corresponding key isn’t present (perhaps consumed on encrypt).
- File has BOM or extra whitespace changing the KID—save as UTF‑8 without BOM.
- If consuming on encrypt, use a separate keys copy for decrypt.
7zip extract failed- Wrong
-ppassword. - Decrypt chain order must be reverse of encrypt (the code does this).
7znot in PATH or archive is corrupted.
- Wrong
7z: command not found- Linux:
sudo apt install p7zip-full - macOS:
brew install p7zip - Windows: install 7‑Zip and add it to PATH.
- Linux: