Hide encrypted messages in photos and text
StegPony encrypts a message or a file and hides it in the fine detail of an ordinary photo, or in text you can paste anywhere. Nothing in the file marks it: no header, no marker, no fixed layout, and without the right passphrase or key the image is just a photo. How hard it is to detect depends on how much you hide, and the app rates that before you hide it.
Android, in testing. Release candidates are published here and on GitHub. Version 1.0 will come to F-Droid and as a direct download.
How it works
-
Pick a cover
Take a photo with StegPony's camera, or pick one you took yourself and haven't shared anywhere.
-
Write the message
Type text or pick a file. The capacity meter shows how much fits and how detectable the result would be.
-
Lock it
Use a passphrase or someone's public key. Add a decoy under a second passphrase if you want one.
-
Send the file
Send the image as a file or document. The recipient opens it in StegPony with the passphrase or their key.
Features
Hiding
- JPEG photos
- The message goes into the photo's own compressed data, so it stays a JPEG with your camera's compression, like any other photo from your phone.
- Lossless PNG
- For images that were PNGs to begin with, such as screenshots and graphics.
- Text
- As a run of ordinary words that reads as nonsense, or as invisible characters inside a message you write. Both hold far less than a photo and are labelled honestly in the app.
- Detectability rating
- Low, medium or high, from tests with a standard detector on real phone photos, shown before you hide.
- Files too
- Hide any file that fits, including an age or PGP file from AgePony or PGPony.
- Telegram photos from an iPhone
- Experimental. StegPony prepares a copy of the photo the way Telegram on an iPhone would, so the message should survive being sent as a photo there. Not verified yet: send one to yourself first.
Keys
- Passphrases
- Stretched with Argon2id, so guessing is slow.
- Public keys
- Hide for someone's age key or Curve25519 OpenPGP key; only their secret key opens it.
- Hardware keys
- Open hidden messages with an OpenPGP card over NFC or USB. The secret stays on the card.
- Contacts and QR codes
- Add contacts by QR code, by pasting a key, from a file, or shared in from another app such as PGPony.
On your phone
- Decoy
- A second message under a second passphrase. Nobody can tell whether an image has one.
- No network access
- The app has no internet permission at all.
- App lock and screenshot blocking
- Fingerprint, face or screen lock to open the app. Reveal and Keys always block screenshots.
- Launcher disguise
- Show the app as Photo Tools, Notes or Utilities in the launcher. It slows down a casual look; the real name still shows in Android's app settings.
- Cover reuse warning
- StegPony remembers fingerprints of covers you've used, on the phone only, and warns before one is used again.
- Metadata removed
- Location, time and device details are stripped from the output by default.
Sending the image
What's hidden survives only if the file arrives unchanged, or changed in a way StegPony has prepared for. These are the results so far, from real sends.
| How you send it | Result | Notes |
|---|---|---|
| As a file or document, by email, USB, RelayPony or cloud storage that keeps files unchanged | Works | The file arrives byte for byte, which is all StegPony needs. Some cloud and photo services re-save images, so check yours. |
| Telegram photo, sent from an iPhone through the photo gallery | Experimental | Choose "Telegram photo from an iPhone (experimental)" when hiding, save the image to Photos and send it from Telegram's gallery in standard quality, not HD, one per message. In early tests, including one copy made by the app, everything hidden came through intact. Not verified yet: send one to yourself first. |
| Telegram photo sent from Android, or attached on an iPhone with Attach, then File | Not yet | In tests, Telegram re-saved both of these at a different quality, which destroys what's hidden. |
| WhatsApp or Signal photo | Not yet | Both recompress photos. Measurements so far show they need an error-tolerant mode, which is planned. |
| Hidden text in a message | Depends on the app | Words survive as long as no word is changed, so watch for autocorrect. Many apps remove invisible characters, so send yourself a test first. |
Never send or post the original photo as well. Anyone holding both can compare them.
What StegPony can't protect against
Hiding lowers the odds of being noticed; it doesn't make them zero. The app's Help says the same thing in more detail.
- Someone who has the original photo you hid in.
- A detector trained on photos from your own camera, especially with a lot hidden.
- Someone who knows StegPony is installed and insists on a second passphrase.
- A forensic examination of your unlocked phone.
- Anyone who sees whom you send images to, and when. StegPony hides what you send, not that you sent it.
Technical details
- Passphrase
- Argon2id, 128 MiB, 3 passes, 4 lanes
- Public key
- X25519 with Elligator 2, HKDF-SHA256
- Encryption
- ChaCha20-Poly1305
- Layout
- No header, no length or version in the clear; padded to fixed sizes
- Slots
- Two in every carrier: payload plus decoy or random filler
- Code
- Ternary syndrome-trellis code
- JPEG
- AC coefficients, J-UNIWARD costs, no re-encoding
- PNG
- Pixel values, HILL costs
- Text
- 4,096-word English list, or zero-width characters
- Positions
- Keyed permutation from the passphrase, or from the recipient's public key in public-key mode (anyone with that key can find the positions, not read them)
- Platform
- Android 8.0 or later, arm64-v8a and x86_64
- Core
- StegPonyCore, in Rust, written to be shared across platforms
- Permissions
- Camera (in-app photos and QR codes) and NFC (hardware keys); no internet
- Keys at rest
- Encrypted with an Android Keystore key, left out of backups
- License
- Apache-2.0
Source code
Everything is open source. The format is written down, with test vectors, so the scheme can be checked on its own.
- StegPonyAndroid
The Android app, in Kotlin and Jetpack Compose.
- StegPonyCore
The Rust core: format, envelope, carriers and the app bindings. FORMAT.md is the specification.
FAQ
Can anyone tell that a photo has something hidden in it?
Why can't I send the image as a normal photo in WhatsApp or Signal?
What is the decoy?
Does it work with my age or PGP keys?
Can I open hidden messages with a hardware key?
Is there an iPhone or desktop version?
Where do I get it?
Download
StegPony is in testing. The latest release candidate is 1.0.0-rc3, from October 29, 2026. It is a test build for Android, signed and published with its SHA-256 so you can check it.