Skjul hemmelig tekst i billeder (steganografi)
Steganografi er kunsten at skjule en besked inde i noget andet, så det ikke er tydeligt, at der overhovedet findes en besked. Denne guide viser, hvordan du gemmer hemmelig tekst inde i pixlerne i et helt almindeligt billede og henter den frem igen, gratis og helt i din browser. Intet forlader din computer.
Sådan virker det
Et billede består af pixels, og hver pixel har tre farveværdier: rød, grøn og blå, hver fra 0 til 255. Tallet 200 skrives binært som 11001000. Hvis du ændrer den allersidste ciffer, den mindst betydende bit, får du 201, altså 11001001. Forskellen på farven mellem 200 og 201 er så lille, at øjet umuligt kan se den. Det er hele tricket: den sidste bit i hver farveværdi er “gratis” plads, hvor du kan gemme data, uden at billedet ser anderledes ud.
Beskeden bliver først lavet om til tal. Hvert bogstav er en byte på 8 bits. Bogstavet “H” er tallet 72, som binært er 01001000. De 8 bits fordeles ud på 8 pixels, én bit per farveværdi, ved at overskrive netop den mindst betydende bit. For at læse beskeden igen samler dekoderen bare de sidste bits op i samme rækkefølge og bygger bytesene tilbage til tekst. Denne metode kaldes LSB-steganografi (Least Significant Bit).
Hvor meget kan du skjule
Kapaciteten afhænger af, hvor mange pixels billedet har, og hvor mange farvekanaler du bruger. Med kun den røde kanal gemmer du 1 bit per pixel. Bruger du rød, grøn og blå sammen, cirka tredobler du pladsen, fordi du får 3 bits per pixel.
| Billedstørrelse | Rød kanal | RGB (3 kanaler) |
|---|---|---|
| 100x100 px | ca. 1,2 KB | ca. 3,6 KB |
| 1280x720 px | ca. 115 KB | ca. 345 KB |
| 1920x1080 px | ca. 259 KB | ca. 778 KB |
I vores koder kan du selv vælge, om du vil bruge Rød, RGB eller RGBA. Jo flere kanaler, jo mere tekst er der plads til, men jo mindre diskret bliver ændringen. Til korte beskeder er den røde kanal rigeligt, og den ændrer billedet mindst.
Skjul en besked
Upload et billede, skriv din tekst, og hent det færdige billede. Prøv det her:
Trinene er: vælg et billede, skriv beskeden, vælg eventuelt RGB i stedet for kun Rød, hvis du har brug for mere plads, angiv eventuelt en adgangskode, og klik på Kod og download. Resultatet gemmes altid som PNG. Det er vigtigt, fordi PNG er tabsfri og bevarer hver eneste bit præcist. JPEG er derimod tabsgivende: formatet omregner farverne for at spare plads, og det ville ødelægge de skjulte bits, så beskeden ikke længere kan læses.
Afsløre en besked
Har du et billede med en skjult besked, kan du læse den her. Slip PNG-en, og teksten dukker frem:
Var beskeden beskyttet med en adgangskode, skriver du adgangskoden for at få den frem i klartekst. Dekoderen er fleksibel og genkender automatisk mange forskellige LSB-formater, ikke kun dem, vores koder selv laver. Den prøver forskellige kanalvalg (R, RGB, RGBA samt kun G eller kun B), både beskeder med et længdepræfiks og beskeder afsluttet med et null-tegn, og begge bitrækkefølger (MSB og LSB). Den bruger streng validering undervejs, så et helt almindeligt billede uden skjult tekst bare giver et tomt resultat i stedet for volapyk.
Tilføj en adgangskode (kryptering)
Angiver du en adgangskode i koderen, bliver beskeden krypteret med AES-256-GCM, før den lægges ind i pixlerne. Nøglen udledes af din adgangskode med PBKDF2, som strækker den, så den er dyr at gætte sig til. Effekten er, at de skjulte bits kommer til at ligne ren tilfældig støj. Uden den rigtige adgangskode afslører de intet, og en forkert adgangskode afslører heller intet, fordi GCM’s godkendelsestag afviser data, der ikke passer.
Det er værd at forstå forskellen. Steganografi skjuler, at der overhovedet findes en besked. Kryptering gør beskeden ulæselig, selv hvis nogen finder den. Bruger du dem sammen, får du begge dele: en modstander skal både opdage, at der er noget gemt, og derefter bryde krypteringen. Det er markant stærkere end hver metode for sig.
Grænser og typiske fejl
Metoden er robust, men den har klare grænser, og det er bedre at kende dem på forhånd.
Den virker kun på tabsfrie PNG-billeder. Gemmer du billedet igen som JPEG, tager et skærmbillede af det eller beskærer det, ryger de skjulte bits, og beskeden er væk. De fleste chat-apps og sociale netværk komprimerer billeder på ny, når du deler dem, og det fjerner også beskeden. Vil du sende et kodet billede videre, så del PNG-filen direkte som en fil (for eksempel som vedhæftning eller via en tjeneste, der ikke rører filen), ikke gennem en kanal, der komprimerer igen.
Husk også, at dette er LSB-steganografi. Vores dekoder er ikke en universel detektor, der kan afkode enhver tænkelig metode. Der findes for eksempel steganografi, der gemmer data i JPEG’s DCT-domæne i stedet for i pixlernes sidste bit, og den slags kan værktøjet her ikke læse.
Ofte stillede spørgsmål
Er det privat? Ja. Alt kører lokalt i din browser via Canvas API. Billedet og beskeden bliver behandlet på din egen enhed, og der uploades intet til nogen server.
Kan jeg bruge et hvilket som helst billede? Du kan bruge de fleste almindelige billeder som udgangspunkt, men resultatet gemmes altid som PNG, fordi det er tabsfrit. Vælg helst et billede med nok pixels til den mængde tekst, du vil skjule. Fotos med mange detaljer skjuler ændringen bedst.
Ser det kodede billede anderledes ud? Nej, ikke for det blotte øje. Kun den mindst betydende bit i de valgte farvekanaler ændres, og forskellen mellem for eksempel 200 og 201 er umulig at se. Bruger du kun den røde kanal, er ændringen allermindst.
Kan nogen læse det uden adgangskoden? Uden adgangskode ligger teksten skjult, men i princippet læsbar, hvis nogen mistænker LSB-steganografi og prøver at afkode billedet. Med en adgangskode er beskeden krypteret med AES-256-GCM, og så er den ulæselig uden den rigtige adgangskode. En forkert adgangskode giver intet.
Klar til at prøve? Brug Steganografi-koderen til at skjule din besked og Steganografi-dekoderen til at hente den frem igen.