
Steganografie-Tool für JPG-Bilder
jdvrif (JPG Data Vehicle) ist ein schnelles, einfach zu bedienendes Steganografie-Kommandozeilenwerkzeug zum Verbergen und Extrahieren beliebiger Dateitypen über ein JPG-Bild. Nur Linux.
Ihre Datendatei wird mit libdeflate/zlib komprimiert, dann mit XChaCha20-Poly1305 (libsodium secretstream) unter einem Schlüssel verschlüsselt, der durch Argon2id aus einer zufällig generierten Wiederherstellungs-PIN abgeleitet wird, und schließlich in das Trägerbild eingebettet. Die PIN wird einmalig am Ende von conceal angezeigt und nirgendwo gespeichert: Ohne sie kann die verborgene Datei nicht wiederhergestellt werden.
Im Standard-Verbergungsmodus können Sie jeden Dateityp verbergen, wobei das fertige Bild auf 2GiB begrenzt ist. Die anderen Plattform-Verbergungsmodi und die kompatiblen Social-Media-Seiten (unten aufgeführt) haben ihre eigenen deutlich kleineren Größenbeschränkungen und weitere Anforderungen.
Es gibt eine Web-Edition von jdvrif, die Sie sofort nutzen können – eine praktische Alternative zum Herunterladen und Kompilieren des CLI-Quellcodes. Web-Datei-Uploads sind auf 20MiB begrenzt.
Eine experimentelle Rust-Portierung jdvrif-rs ist ebenfalls für Interessierte dieser Sprache verfügbar. Sie ist formatkompatibel: Jeder der beiden Builds kann die Bilder des anderen wiederherstellen.
jdvrif leitet sich teilweise von der implementierten Technik des Sicherheitsforschers David Buchanan ab.

Demo-Bild: „A place of concealment" / PIN: 7912872750612437051
Anders als die gängige LSB-Steganografiemethode (Least Significant Bit), bei der Daten in den Pixeln eines Trägerbilds verborgen werden, versteckt jdvrif Daten größtenteils in Anwendungssegmenten eines JPG-Bilds (ICC, EXIF, XMP usw.).
| Verbergungsmodus | Wohin die Daten gelangen | Wo das Ausgabebild geteilt werden kann |
|---|---|---|
| (keine Option) | APP2/ICC-Profilesegmente | X-Twitter, Tumblr, Mastodon, Pixelfed, PostImage, ImgBB, ImgPile, Flickr |
| -b | gerahmte EXIF-/Photoshop-/XMP-Segmente | nur Bluesky |
| -r | JPEG-DCT-Koeffizienten (QIM) | nur Reddit |
| -x | JPEG-DCT-Koeffizienten (J-UNIWARD/STC) | nur X-Twitter |
Die beiden Plattform-Ausnahmen von der standardmäßigen Segment-Speichermethode sind Reddit und X-Twitter. Beide haben ihren eigenen Verbergungsmodus, und keiner dieser Modi verwendet überhaupt Metadatensegmente: -r und -x tragen die Nutzlast stattdessen in den DCT-Koeffizienten des JPG-Bilds.
Reddit kodiert hochgeladene Bilder neu und verwirft dabei die Metadatensegmente, auf die der Standardmodus angewiesen ist, sodass -r der einzige Modus ist, der dort funktioniert. X-Twitter bewahrt ein einzelnes, kleines ICC-Segment, sodass der Standardmodus auf dieser Plattform weiterhin funktioniert – allerdings nur für eine winzige Nutzlast.
Für den Reddit-Verbergungsmodus (-r) verwenden wir die QIM-Steganografiemethode (JPEG-DCT-Domain Quantization Index Modulation), da dies die einzige Speichermethode ist, die derzeit für Reddit funktioniert. Das Trägerbild wird auf Baseline Q75 4:2:0 transkodiert, und die Nutzlast wird in seinen Luminanz-DCT-Blöcken getragen.
Um die Speicherkapazität für die Reddit-Plattform zu maximieren, verwenden Sie ein Trägerbild mit großen Abmessungen, 2048x2048, 4096x4096, 8192x8192 (max) usw.
Die Qualität des Trägerbilds ist für diese Methode nicht wichtig und sollte bei den größten Abmessungen niedrig gehalten werden, um die Dateigröße des Trägerbilds möglichst gering zu halten.
Während die X-Twitter-Plattform die von jdvrif bereitgestellte Standardmethode verwenden kann, bei der Daten in APP2/ICC-Segmenten verborgen werden, beschränkt X-Twitter dies auf ein einzelnes ICC-Segment mit einer maximalen Größe von nur ~10KiB.
Um mehr als diese ~10KiB zu übertragen, verwende den Verbergungsmodus der X-Twitter-Plattform (-x). Er verzichtet vollständig auf Metadatensegmente — es wird nichts in ein ICC-Profil geschrieben — und nutzt stattdessen die adaptive J-UNIWARD-Steganographiemethode mit Syndrome-Trellis Coding (STC). Das Cover wird auf progressives 4:2:0 in seiner quellabgeleiteten Qualität (begrenzt auf Q97) transkodiert.
Um die Speicherkapazität für die X-Twitter-Plattform zu maximieren, verwende ein hochwertiges/detailliertes Cover-Bild mit großen Abmessungen, 1024x1024, 2048x2048, 4096x4096 (max) usw.
Die Träger -r und -x verschlüsseln deine Daten und binden ihre Position über Argon2id an deine Wiederherstellungs-PIN, aber das Einbetten verändert dennoch die DCT-Statistik des Bildes, sodass dedizierte Steganalyse aufdecken kann, dass ein Bild versteckte Daten enthält.
Mit jdvrif v9.0 erstellte -r- und -x-Bilder bleiben wiederherstellbar, aber v9.0 kann keine mit v9.1 erstellten -r- oder -x-Bilder wiederherstellen.
Beide DCT-Modi tragen weit weniger Daten als der Standardmodus, daher solltest du mit capsize ein Cover-Bild vermessen, bevor du eine Nutzlast wählst (siehe Kapazität prüfen).
Zum Bauen sind CMake 3.20 oder neuer, flock aus util-linux und entweder Ninja (bevorzugt) oder Make erforderlich. Der Compiler muss GCC 14 oder neuer sein, oder Clang 18 oder neuer in Kombination mit einer C++23-Standardbibliothek, die Funktionen wie std::format und std::print implementiert. Die benötigten nativen Bibliotheken sind libsodium, libjpeg-turbo (sowohl die turbojpeg- als auch die libjpeg-APIs), zlib und libdeflate. OpenMP ist optional: Wenn vorhanden, parallelisiert es den -x-J-UNIWARD-Kostendurchlauf.
$ sudo apt update
$ sudo apt install g++ cmake ninja-build util-linux libsodium-dev libturbojpeg0-dev libjpeg-dev zlib1g-dev libdeflate-dev
$ g++ --version # confirm the reported version is 14 or newer
$ chmod +x compile_jdvrif.sh
$ ./compile_jdvrif.sh
$ sudo cp jdvrif /usr/bin
Wenn Ihre Distribution GCC 14 als versioniertes Paket bereitstellt, installieren Sie g++-14 und bauen Sie mit CXX=g++-14 ./compile_jdvrif.sh.
Der Wrapper legt abhängigkeitsverfolgte Objektdateien unter src/build/ ab, sodass spätere Aufrufe nur das neu bauen, was sich geändert hat, und er ersetzt die veröffentlichte jdvrif-Binärdatei erst nach einem vollständigen, erfolgreichen Build. Setzen Sie JDVRIF_JOBS=<count>, um das Parallelitätslimit zu ändern (Standard: CPU-Anzahl, begrenzt auf 8), JDVRIF_BUILD_DIR=<path>, um einen separaten Build-Cache zu verwenden, oder BUILD_MODE=sanitize für einen ASan/UBSan-Build.
$ jdvrif
Usage: jdvrif conceal [-b|-r|-x] <cover_image> <secret_file>
jdvrif recover <cover_image>
jdvrif capsize [-r|-x] <cover_image>
jdvrif --info
Führen Sie jdvrif --info aus, um die vollständige integrierte Anleitung zu Modi, Plattformoptionen und Größenbeschränkungen zu erhalten.
$ jdvrif conceal your_cover_image.jpg your_secret_file.doc