Geheime tekst verbergen in afbeeldingen (steganografie)
Steganografie is het verstoppen van een bericht in iets onschuldigs, zodat niemand vermoedt dat er überhaupt een bericht is. In deze gids verberg je geheime tekst in de pixels van een gewone afbeelding en lees je die er later weer uit, gratis en volledig in je browser. Niets wordt geüpload; alle bewerkingen gebeuren lokaal op je eigen apparaat.
Hoe het werkt
Een digitale afbeelding is een raster van pixels, en elke pixel heeft een rood-, een groen- en een blauwwaarde tussen 0 en 255. Die waarden zijn opgeslagen als bytes van 8 bits. Het idee achter LSB-steganografie (van “least significant bit”, de minst-significante bit) is simpel: je verandert alleen de allerlaatste bit van zo’n waarde. Dat is de bit met het kleinste gewicht, dus het verschil is hooguit één stapje op een schaal van 256.
Een voorbeeld. Stel dat de rode waarde van een pixel 200 is, binair 11001000. Verander je de laatste bit naar een 1, dan wordt het 201, binair 11001001. Voor het menselijk oog is het verschil tussen rood 200 en rood 201 volstrekt onzichtbaar. Precies daarin schuilt de truc: je hebt nu één bit vrije opslag zonder dat iemand het ziet.
Het bericht wordt bit voor bit in die laatste bits geschreven. Neem de letter “H”. In tekst is dat het getal 72, binair 01001000. Die 8 bits worden verdeeld over 8 pixels: de eerste pixel krijgt in zijn minst-significante bit een 0, de tweede een 1, de derde een 0, enzovoort. Bij het uitlezen loop je dezelfde pixels weer af, plukt je uit elk de laatste bit en zet je die acht bits terug in elkaar tot de byte 72, oftewel de “H”. Zo gaat het door voor elke letter van het bericht.
Hoeveel kun je verbergen
Per pixel kun je met één kanaal (bijvoorbeeld alleen rood) precies 1 bit kwijt. Gebruik je rood, groen en blauw samen, dan wordt dat 3 bits per pixel en verdrievoudigt de capaciteit ongeveer. Onze encoder laat je die keuze maken: Rood, RGB of RGBA. Ruwe cijfers, als richtlijn:
| Afmeting | Alleen rood | RGB (3 kanalen) |
|---|---|---|
| 100 x 100 px | ≈ 1,2 KB | ≈ 3,6 KB |
| 1280 x 720 px | ≈ 115 KB | ≈ 345 KB |
| 1920 x 1080 px | ≈ 259 KB | ≈ 778 KB |
Voor een handjevol zinnen is zelfs een kleine afbeelding ruim voldoende. Wil je een lang bericht verstoppen, kies dan een grotere foto of schakel over naar RGB (of RGBA voor nog iets meer ruimte).
Verberg een bericht
Upload een afbeelding, typ je tekst en klik op coderen. Hieronder staat de echte encoder, klaar voor gebruik:
De stappen op een rij: upload een afbeelding, typ het bericht, kies eventueel RGB in plaats van Rood als je meer ruimte nodig hebt, stel eventueel een wachtwoord in, klik op Coderen en download het resultaat. De uitvoer is altijd een PNG, en dat is geen toeval. PNG is verliesvrij: elke pixel blijft exact zoals je hem hebt geschreven, inclusief die zorgvuldig gezette laatste bits. JPEG daarentegen is lossy en gooit bij het comprimeren precies dat soort subtiele detail weg, waardoor je verborgen bits vernietigd zouden worden. Sla het bericht dus nooit op als JPEG.
Onthul een bericht
Heb je een PNG met een verborgen bericht ontvangen? Sleep hem in de decoder hieronder en de tekst verschijnt:
Sleep de PNG erin en lees de verborgen tekst uit. Was het bericht met een wachtwoord beveiligd, typ dan het wachtwoord om het leesbaar te maken. Handig detail: de decoder probeert niet alleen ons eigen formaat te lezen. Hij detecteert automatisch een breed scala aan LSB-varianten, in de kanalen R, RGB, RGBA, G of B, met een lengteprefix of een null-afsluiting, en zowel met bitvolgorde MSB als LSB. De validatie is streng genoeg dat een gewone foto zonder verstopt bericht netjes leeg terugkomt in plaats van willekeurige onzin te tonen.
Een wachtwoord toevoegen (versleuteling)
Stel je een wachtwoord in, dan wordt het bericht eerst versleuteld met AES-256-GCM, waarbij de sleutel uit je wachtwoord wordt afgeleid via PBKDF2. Het versleutelde resultaat gaat vervolgens de pixels in. Het gevolg: zonder het juiste wachtwoord zien die laatste bits eruit als willekeurige ruis en onthullen ze niets. Een verkeerd wachtwoord levert ook niets op, want de authenticatietag van GCM merkt de fout op en weigert nep-uitvoer te produceren.
Dat is het onderscheid dat de moeite waard is om te onthouden. Steganografie verbergt dat er een bericht is. Versleuteling maakt het bericht onleesbaar, zelfs als iemand het vindt. Alleen samen zijn ze echt sterk: eerst valt niet op dat er iets verstopt zit, en mocht iemand toch de verstopplek vinden, dan staat hij nog steeds voor een muur van ruis.
Grenzen en veelgemaakte fouten
Eerlijk is eerlijk, LSB-steganografie is fragiel. Een paar dingen om rekening mee te houden:
- Het werkt alleen op verliesvrije PNG. Sla je de afbeelding opnieuw op als JPEG, of maak je er een screenshot van, dan is het bericht weg.
- Veel chat-apps en sociale netwerken hercomprimeren afbeeldingen automatisch bij het uploaden. Die hercompressie wist je verborgen bits net zo goed. Deel de PNG daarom als bestand (bijvoorbeeld als bijlage), niet via een kanaal dat de afbeelding onderweg omzet.
- Dit is LSB-steganografie, geen universele detector. De decoder herkent veel LSB-varianten, maar geen berichten die met een heel andere methode zijn verstopt, zoals steganografie in het DCT-domein van JPEG.
Kort gezegd: behandel de gecodeerde PNG als een breekbaar origineel. Elke keer dat het bestand ergens doorheen gaat dat de pixels aanraakt, loop je het risico het bericht te verliezen.
Veelgestelde vragen
Is dit privé? Ja. Alles draait lokaal in je browser via de Canvas API. Je afbeelding, je bericht en je wachtwoord verlaten je apparaat niet en worden nergens geüpload of opgeslagen.
Kan ik elke afbeelding gebruiken? Vrijwel elke afbeelding die je kunt inladen werkt, zolang het resultaat maar als PNG wordt opgeslagen. Grotere afbeeldingen bieden meer ruimte. Foto’s met veel detail en variatie zijn iets discreter dan grote egale vlakken.
Ziet de gecodeerde afbeelding er anders uit? Nee, niet voor het blote oog. Er verandert per aangeraakt kanaal maximaal 1 waarde per pixel, wat visueel niet te onderscheiden is van het origineel.
Kan iemand het zonder het wachtwoord lezen? Als je een wachtwoord hebt ingesteld: nee. Het bericht is versleuteld met AES-256-GCM en zonder het juiste wachtwoord komt er niets leesbaars uit. Zonder wachtwoord kan iemand die de juiste LSB-methode raadt of automatisch detecteert de tekst wel gewoon uitlezen, dus gebruik een wachtwoord voor alles wat echt gevoelig is.
Klaar om te beginnen? Verberg je bericht met de Steganografie Encoder en lees het later weer uit met de Steganografie Decoder.