Tools to decrypt files encrypted by STOPDjvu ransomware. Thanks to Emsisoft for the decryption logic, keystream generation logic and all my below understanding comes from them.
Verification Status: The keystream extraction and validation logic is fully verified. With structural checks (enc_size == orig_size + 78 and unencrypted tail comparison), extracted keystreams in keystream_db.json match Emsisoft's server keys 100% byte-for-byte across all supported file salts.
What hackers do:
- Generate Master Key - Hackers possess a master key which they use to encrypt files
- Create Unique System ID - Each infected system gets a unique 40-character ID like "BE7eWxxxxxxxxfwHY" (total length 40 chars), This is what makes your personal ID as well (in my case it was "014{{unique-id}}" so this one is 43 characters)
- Extract File Salt - Get 5-byte salt from the beginning of each file (first 5 bytes)
- XOR Encrypt - Use master key + system ID + file salt to generate keystream, then XOR encrypt only the first ~150KB of each file
- Add .djvu extension -
document.pdfbecomesdocument.pdf.djvu - Insert metadata - Adds the system ID and salt info to each file
- Leave marker - Special Constant byte sequence to identify encrypted files
File structure after encryption:
[5-byte Salt]
[Encrypted Data] (~150KB)
[Original Data] (Remaining)
[40-byte System ID]
[Marker]
Why only partial encryption?
- Faster encryption process
- Files keep most original data intact
- Makes victims think files are "broken" not encrypted
Two types of system IDs:
- Offline IDs - Can be decrypted if we have the keystream
- Online IDs - Need the actual master key (usually impossible)
How decryption works step by step:
- File Validation - Check for STOPDjvu marker bytes to confirm it's encrypted
- Extract System ID - Get 40-char unique system ID from file footer (last 78 bytes)
- Extract Salt - Get 5-byte salt from file header (first 5 bytes)
- Find Matching Keystream - Look for keystream with matching system ID and salt:
- First check local JSON files (api_keystreams.json, keystream_db.json)
- If not found, query Emsisoft API
- XOR Decryption - XOR the encrypted portion (first ~150KB) with the keystream to get original data
- File Assembly - Combine decrypted header + original unencrypted tail data
- Clean File - Remove ransomware footer/metadata to get identical original file
Files of the same type with the same file format version usually have the same salt ID. This means:
- If you extract a keystream from one file pair (original + encrypted)
- You can use that same keystream to decrypt other files having the same salt ID
- This is why one successful keystream extraction can help decrypt multiple files from the same system
- Example: All PDF files created by the same PDF software version on the same infected system will likely share the same salt
- So, if you have 1 original file for the each File-Salt-IDs then you can decrpt all your files
For large files where no server key or original pair exists, partial encryption leaves the unencrypted tail (>150 KB) intact:
- MPEG-2 TS / AVCHD Video (
.mts,.ts): Over 99% of large videos is untouched raw video/audio.recover_tail.pylocates recurring 192-byte BDAV packets with0x47sync bytes, trims the 78-byte ransomware footer, and aligns the stream to packet boundaries so media players (VLC, MPC-HC) can immediately play the footage. - Archive Streams (
.rar): Intact compressed file blocks in the unencrypted tail can be detected and wrapped with standard container headers to extract the undamaged files inside. - Empty Files (
.nomedia): Restored directly to 0 bytes.
-
Pre-existing Zero Allocations: If a file has salt
00 00 00 00 00and its unencrypted tail contains 100% zeroes, the file was already a corrupted/zero-filled allocation (e.g., from an SD card write interruption or power loss) prior to infection. Decrypting$0 \oplus Keystream$ mathematically yields pure zeroes, so it cannot open as a valid media file. -
Temporary Lock Files (
~$...): Small (240-byte) temporary owner files created by Microsoft Office during editing; they can be safely ignored once the main documents are decrypted.
file_test.py- Detect whether a file is encrypted by STOPDjvu and display extracted metadata (5-byte salt, 40-char system ID, marker) and keys for your system ID from Emsisoft if existsextract_keystream.py- Extract keystreams from original/encrypted file pairs with strict structural and tail verificationcompare_keystreams.py- Compare extracted keys with server keysdecrypter.py- Main decrypter (automatically loads localkeystream_db.jsonandapi_keystreams.json, then tries API)recover_tail.py- Format-aware stream recovery for files without keystreams (MTS video sync alignment, RAR archive tail extraction)
Extract keystreams from file pairs:
python extract_keystream.py ./original/ ./encrypted/Decrypt single file:
python decrypter.py document.pdf.djvuDecrypt entire directory:
python decrypter.py ./encrypted_files/ ./decrypted_files/Use local keystream database (optional; loaded automatically if present in folder):
python decrypter.py ./encrypted_files/ ./output/ --local-db keystream_db.jsonRecover partial streams without keys (MTS video / archive tail):
python recover_tail.py ./encrypted_files/video.mts.djvu ./decrypted_files/video.mts- Based on Emsisoft's research and decryption logic: https://www.emsisoft.com/ransomware-decryption/stop-djvu/
- File pair upload site to generate keystreams: https://decrypter.emsisoft.com/submit/stopdjvu/
- Emsisoft's STOPDjvu Decrypter tool to decrypt your files: https://www.emsisoft.com/en/ransomware-decryption/download/stop-djvu