The fencrypt
program implements encrypted search for text and binary files greater than 32 bytes. Supports all unicode characters.
This program also encrypts and decrypts files using a four-round feistel cipher, and supports encrypted search and ciphertext tamper detection with HMAC-SHA-256.
Encrypt:
fencrypt -e <file_name>
Decrypt:
fencrypt -d <file_name>
Search:
fencrypt -s "string"
Search supports word prefix:
fencrypt -s string*
β― ./fencrypt -h
usage: fencrypt [-h] [-d] [-e] [-s] [-v] inputs [inputs ...]
Encrypts and decrypts binary and text files. Plaintext search on encrypted files.
positional arguments:
inputs file path or search string
optional arguments:
-h, --help show this help message and exit
-d decrypt
-e encrypt
-s search
-v verbose output to terminal
β― make clean all
# https://www.gutenberg.org/ebooks/2264
curl -s https://www.gutenberg.org/cache/epub/2264/pg2264.txt | tee macbeth.txt.plain > macbeth.txt
encrypting with password: 'macbeth.txt'
echo -n macbeth.txt | ./fencrypt -e -v macbeth.txt
{
"macbeth.txt": "4241a8f0f9711be7ef8df0f78280c827dd95bbe1c15983f98194e5bc365707e2"
}
# https://www.gutenberg.org/ebooks/17996
curl -s https://www.gutenberg.org/files/17996/17996-0.txt | tee aeschylus.txt.plain > aeschylus.txt
encrypting with password: 'aeschylus.txt'
echo -n aeschylus.txt | ./fencrypt -e -v aeschylus.txt
{
"aeschylus.txt": "a8aded8f6c715ae675f9cfc5fea5bd2a902284fa2f4732c2b001e425bf7082c8"
}
# https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
curl -s https://upload.wikimedia.org/wikipedia/commons/f/f0/Tux_ecb.jpg | tee ecb.jpg.plain > ecb.jpg
encrypting with password: 'ecb.jpg'
echo -n ecb.jpg | ./fencrypt -e -v ecb.jpg
{
"ecb.jpg": "4140d3287a64918b56c80de058936c047b2f86c72021d4be95e7471a97fbc7d1"
}
echo -n wrongpassword | ./fencrypt -s crickets
echo -n macbeth.txt | ./fencrypt -s haha
echo -n macbeth.txt | ./fencrypt -s -v crickets
Incorrect password for file .fenc-meta.aeschylus.txt.
Incorrect password for file .fenc-meta.ecb.jpg.
{
"macbeth.txt": "4241a8f0f9711be7ef8df0f78280c827dd95bbe1c15983f98194e5bc365707e2"
}
macbeth.txt
echo -n macbeth.txt | ./fencrypt -s cric*
macbeth.txt
echo -n aeschylus.txt | ./fencrypt -s άδΟΞ±ΟΟΞΏΟ
aeschylus.txt
echo -n aeschylus.txt | ./fencrypt -s άδΟΞ±Ο*
aeschylus.txt
ascii art π
βββββββββββββββββββββββββββββββββββββββββββββββ
β plaintext β
β (any length) ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββ only if plaintext is text, not binary β
β β
β β
first β rest β
16 bytes β bytes β
ββββββββββββββββββββββββββββββββ β
β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββ
βAES-CTR round β β β βMaster Key β βindexing text β
β β β β β β β β
β βΌ βΌ β β β β ββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββ ββββββββββββββββ β β ββββββββββββββββ ββββββββββββββββ β β β β β
β β left β β right β β β β password β β salt β β β β extract words β β
β β (16 bytes) β β (rest bytes) β β β β (any length) β β (16 bytes) ββββββββββββββββββ β β (4-12 code points long) β β
β ββββββββββββββββ ββββββββββββββββ β β ββββββββββββββββ ββββββββββββββββ β β β β β β
β β β β β β β β β β ββββββββββββββββββββββββββββββββββββ β
β β β β β βΌ βΌ β β β β β
β ββββββββββ β β β βββββββββββββββββββββββββββββββββββββββββββ β β β βββββββββββββββββββ΄βββββββββββββββββ β
β β 16 β β β β β PBKDF2-HMAC-SHA256 β β β β β β β
β β β β β β β (250,000 iterations) β β β β βΌ βΌ β
β β βΌ β β β βββββββββββββββββββββββββββββββββββββββββββ β β β ββββββββββββββββ ββββββββββββββββ β
β β βββββββββββββββββββ 16 β β β β β β β β word β ... β word β β
β β β iv key βββββββββββββββββββββββββββββββββββββ β βΌ β β β β β β β β
β β β AES-CTR β β β β β ββββββββββββββββ β β β ββββββββββββββββ ββββββββββββββββ β
β β βββββββββββββββββββ β β β β β master key β β β β β β β
β β β βΌ β β β β (32 bytes) β β β β β β β
β β βkeystream βββββ β β β ββββββββββββββββ β β β β β β
β β βββββββββββββββΆβxorβ β β β β β β β βΌ βΌ β
β β βββββ β β βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β β β β β β β β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ β β β for each word, generate star search terms β β
β β β βKey Schedule β β β β β (add start between 4-12 code-points) β β
β β β β ββββββββββββββ΄βββββββββββββββ β β β β β β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β β β β β β β β for "building": β β
βHMAC round β β β β β β first 16 second 16 β β β β β β β
β β β β β β βΌ bytes bytes βΌ β β β β * building β β
β βΌ βΌ β β β ββββββββββββββββ ββββββββββββββββ β β β β * buildin* β β
β ββββββββββββββββ ββββββββββββββββ β β β β schedule key β β schedule iv β β β β β * buildi* β β
β β left β β right β β β β β (16 bytes) β β (16 bytes) β β β β β * build* β β
β β (16 bytes) β β (rest bytes) β β β β ββββββββββββββββ ββββββββββββββββ β β β β * buil* β β
β ββββββββββββββββ ββββββββββββββββ β β β β β β β β β β β
β β β β β β β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β β β β β β β β β β β
β β β β β β β βββββββββββββββββββ β β β β β β β
β β βββββββββββββββββββββββββββββββββββββββ β β βββββΆβ key iv ββββββ€ β β β β β β
β β 16 β β β β β β β β AES block β β β β β βΌ βΌ β
β β βΌ β β β β β β βββββββββββββββββββ β β β β ββββββββββββββββ ββββββββββββββββ β
β β βββββββββββββββββββ β β β β β β β β β β β β ββββββββββββββ΄ββ β ββββββββββββββ΄ββ β
β β β key β β β β β β β βΌ β β β β β β ββββββββββββββ΄ββ ... β β ββββββββββββββ΄ββ β
β β β HMAC-SHA256 βββββ€ β β β β β βββββββββββββββββ β β β β βββ€ β search β βββ€ β search β β
β β βββββββββββββββββββ β β β β β β β validator β β β β β βββ€ term β βββ€ term β β
β βΌ β β β β β β β β (16 bytes) ββββββββββββββββββββββββββββββ β ββββββββββββββββ ββββββββββββββββ β
β βββββ β β β β β β β βββββββββββββββββ β β β β β β β
β βxorβββββββββββββββββ MAC β β β β β β β β β β β β β
β βββββ (first 16 bytes) β β β β β β β β β β βΌ βΌ β
β β β β β β β β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β β β β β βββββββββββββββββββ +1 β β β β β β β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β β β βββββΆβ key iv ββββββ€ β β β β casefold and normalize all search terms β β
β β β β β β β AES block β β β β β β β β
β β β β β β βββββββββββββββββββ β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β β β β β β β β β β β
βAES-CTR round β β β β β β β β β β β β β β
β β β β β β β β βββββββββββββββββ β β β β βΌ βΌ β
β βΌ βΌ β β β β β β feistel 1 β β β β β ββββββββββββββββ ββββββββββββββββ β
β ββββββββββββββββ ββββββββββββββββ β β ββββββββββββββββββββββββββ (16 bytes) β β β β β β ββββββββββββββ΄ββ β ββββββββββββββ΄ββ β
β β left β β right β β β β β βββββββββββββββββ β β β β β β ββββββββββββββ΄ββ ... β β ββββββββββββββ΄ββ β
β β (16 bytes) β β (rest bytes) β β β β β β β β β βββ€ β search β βββ€ β search β β
β ββββββββββββββββ ββββββββββββββββ β β β β β β β β βββ€ term β βββ€ term β β
β β β β β β β β β β β ββββββββββββββββ ββββββββββββββββ β
β β β β β β β βββββββββββββββββββ +2 β β β β β β β
β ββββββββββ β β β β βββββΆβ key iv ββββββ€ β β β β β β
β β 16 β β β β β β β AES block β β β β β β β β
β β β β β β β β βββββββββββββββββββ β β β β βΌ βΌ β
β β βΌ β β β β β β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β βββββββββββββββββββ 16 β β β β β βΌ β β β β β β β
β β β iv key βββββββββββββββββββββββββββββββ β β β βββββββββββββββββ β ββββββββββββββββββββββββ€ β HMAC-SHA256 all search terms β β
β β β AES-CTR β β β β β β β β feistel 2 β β β β β β β β β
β β βββββββββββββββββββ β β β βββββββββββββββββββββββββββββ (16 bytes) β β β β β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β βΌ β β β β βββββββββββββββββ β β β β β β β
β β βkeystream βββββ β β β β β β β β β β β
β β βββββββββββββββΆβxorβ β β β β β β β β β β β
β β βββββ β β β β β β β β β βΌ β
β β β β β β β βββββββββββββββββββ +3 β β β β β ββββββββββββββββ β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β β βββββΆβ key iv ββββββ€ β β β β β ββββββββββββββ΄ββ β
β β β β β β AES block β β β β β β β β ββββββββββββββ΄ββ β
β β β β β βββββββββββββββββββ β β β β β βββ€ β mac β β
ββββββββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββββββββββ β β β β β β β β β βββ€ β β
βHMAC round β β β β β β βΌ β β β β β ββββββββββββββββ β
β β β β β β β βββββββββββββββββ β β β β β β β
β βΌ βΌ β β β β β feistel 3 β β β β β β β β
β ββββββββββββββββ ββββββββββββββββ β ββββββββββββββββββββββββββββββββ (16 bytes) β β β β β ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ
β β left β β right β β β β βββββββββββββββββ β β β β β
β β (16 bytes) β β (rest bytes) β β β β β β β β each 32 β
β ββββββββββββββββ ββββββββββββββββ β β β β β β β bytes β
β β β β β β β β β β β
β β β β β β βββββββββββββββββββ +4 β β β β β
β β β β β βββββΆβ key iv ββββββ€ β β β β
β β ββββββββββββββββββββββββββββββββββββ β β β AES block β β β β β β
β β 16 β β β β β β βββββββββββββββββββ β β β β β
β β βΌ β β β β β β β β β β β
β β βββββββββββββββββββ β β β β β βΌ β β β β β
β β β key β β β β β β βββββββββββββββββ β β β β β
β β β HMAC-SHA256 βββββ β β β β β feistel 4 β β β β β β
β β βββββββββββββββββββ β β ββββββββββββββββββββββββββββββββ (16 bytes) β β β β β β
β βΌ β β β β β βββββββββββββββββ β β β β β
β βββββ β β β β β β β β β β
β βxorβββββββββββββββββ MAC β β β β β β β β β
β βββββ (first 16 bytes) β β β β β β β β β
β β β β β β βββββββββββββββββββ +5 β β β β β
β β β β β βββββΆβ key iv ββββββ€ β β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β AES block β β β β β β
β β β β βββββββββββββββββββ β β β β β
β β β β β β β β β β
β β β β βΌ β β β β β
β concatenate bytes β β β βββββββββββββββββ β β β β β
ββββββββββββββββββββββββββββββββ β β β mac β β β β β β
β ββββββββββββββββββββββββββββ (16 bytes) β β β β β β
βΌ β β β βββββββββββββββββ β β β β β
βββββββββββββββββββββββββββββββββββββββββββββββ β β β β β β β β
β ciphertext β β β β β β β β β
β (same length as plaintext) β β β β β β β β β
βββββββββββββββββββββββββββββββββββββββββββββββ β β β βββββββββββββββββββ +6 β β β β β
β β β βββββΆβ key iv+6 ββββββ β β β β
β β β β AES block β β β β β
βΌ β β βββββββββββββββββββ β β β β
βββββββββββββββββββββββββββββββββ β β β β β β β
β HMAC-SHA256 β β β βΌ β β β β
β βββββββββββββββββββββββββββ β βββββββββββββββββ β β β β
βββββββββββββββββββββββββββββββββ β β search β β β β β
β β β (16 bytes) βββββββββββββββ β β β
β β βββββββββββββββββ β β β
β β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β
β mac β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββ
β metadata β
β file β
ββββββββββββββββ
When encrypting, a 32-byte "master" key is generated from a user-supplied password for each file encrypted, using PBKDF2 with HMAC-SHA-256 as the PRF.
The 16-byte salt is randomly generated from a secure random number generator, and stored in the per-file metadata.
A series of 16-byte keys are generated using counter mode:
- AES(Master_key, IV) : a password validator (see below).
- AES(Master_key, IV + 1) : the first round key in the Feistel Cipher
- AES(Master_key, IV + 2) : the second round key in the Feistel Cipher
- AES(Master_key, IV + 3) : the third round key in the Feistel Cipher
- AES(Master_key, IV + 4) : the fourth round key in the Feistel Cipher
- AES(Master_key, IV + 5) : the MAC key.
- AES(Master_key, IV + 6) : the key used for encrypting search terms.
The plaintext file is then encrypted using a four-round feistel cipher, alternating AES CTR mode and HMAC rounds.
UTF-8 encoded text files are indexed for search terms upon encryption. Search terms are any contiguous sequence of Unicode letters (character classes Lu, Ll, Lt, Lm, Lo), non-spacing marks (class Mn), decimel digits (Nd) and connector punctuation (Pc) between 4-12 codepoints. Search terms are casefolded, normalized, then MAC'd using HMAC-SHA-256.
The salt, validator, mac, and hashed search terms are stored in a per-file generated metadata. The password and hash are validated upon decryption.
This program is my final project for the "Applied Cryptography" course in the New York University Masters of Science in Cybersecurity program, Spring 2022.