Stiger · iOS / iMessage

Messages that don't look like messages.

Send a sticker with a message inside. With a password set, only someone with Stiger Pro and the same password can read it. To a curious eye scrolling the chat, it's just a sticker.

Public beta on TestFlight. App Store review in progress. No accounts. No servers. Open spec.

Why now

The messaging environment, in six sourced facts.

Device searches, encryption options and access to messengers differ by country and keep changing. Each item below links to an official or technical source. Stiger doesn't change any of it; it's one more place to put a message that doesn't look like one.

United States · FY2025

55,318 device searches at the border.

92% were basic searches. Under CBP policy, only advanced searches require reasonable suspicion. Source: CBP.

United Kingdom · 2025

Advanced Data Protection withdrawn for UK users.

Apple no longer offers ADP, its opt-in end-to-end encrypted iCloud tier, to new UK users. Privacy Guides ties the change to a UK technical capability notice. Sources: Apple Support, Privacy Guides.

European Union · since 2022

Message scanning rules are under negotiation.

Council position, November 2025: voluntary scanning by providers becomes permanent, mandatory detection orders are left out. Talks with the Parliament were ongoing. Source: Council of the EU.

Russia · 2024–2026

Signal, WhatsApp and Telegram restricted.

Roskomnadzor restricted Signal in August 2024. In February 2026 it removed WhatsApp's domains from the national DNS, and Telegram was reported throttled. Sources: BleepingComputer, 2024, BleepingComputer, 2026, gHacks.

Belarus · Interior Ministry

Subscribing to designated Telegram channels is an offense.

The ministry's GUBOPiK states that subscribing to Telegram channels and chats declared extremist entails administrative liability under Article 19.11: a fine, community service or arrest. Source: GUBOPiK statement.

Venezuela · 2025

Phone checks at road checkpoints.

The IACHR's 2025 annual report records random phone checks in public spaces and, around the 10 January inauguration, at checkpoints nationwide. Source: IACHR (OAS), chapter IV.B.

In real life

What you might use it for.

When messengers are restricted.

In places where mainstream messengers are restricted and phones may be checked, but iMessage still works, a sticker can carry an access key, a contact or instructions, and none of it turns up in a keyword search.

When someone reads your chats.

A partner who scrolls through your messages. A parent who checks. A line to a friend outside, when you need one that doesn't look like one. Set a password and turn on the Face ID lock, and know the limits: the app is visible on your phone, and anyone who knows your passcode can open it.

Things that shouldn't sit in plaintext.

One-time passwords. The wifi for guests. Server access for a friend. The door code for the building. Send the sticker; the string never lands in chat history or in a lock-screen preview.

A note to your future self.

A recovery hint, a locker code, a reminder you don't want in plain text. Send a sticker to yourself — it sits in your Messages history and looks like nothing. Don't make it the only copy of anything critical: a re-compressed image or a forgotten password loses it.

Love notes and inside jokes.

A “miss you” under a cactus sticker. A plan for Saturday the group chat doesn't need to see. It's free and needs no password, but without one, anyone with Stiger can read it. For the ones that matter, set a password.

For the fun of it.

An ARG clue. A note from past-you for the time capsule. An easter egg hidden inside a birthday postcard. Steganography doesn't have to be life-or-death to be a good time.

In 30 seconds

The whole trip, start to finish.

Find Stiger among the iMessage apps, type the secret, set a password, send. On the other end, the sticker opens back into the text.

Recorded on the iOS simulator.

How it works

Open math, hidden in something ordinary.

Your text is encrypted with AES-256-GCM, with a key derived from your password via PBKDF2-SHA256, 600 000 iterations. The ciphertext is then embedded in the least-significant bit of the sticker's blue channel, in a pixel order shuffled by the same password.

Without the password — even knowing exactly which channel and which bit — the hidden bytes read as random: no magic, no length field, nothing that says "Stiger". Random is not the same as untouched, though: statistical steganalysis can tell that something was embedded. It can't tell what.

On the iMessage side, Stiger sends each carrier as a regular image attachment, not through Apple's sticker API. That's a deliberate choice — and a tested one: the sticker API re-encodes images to HEIC and downsamples them in transit (I measured a 512×512 / 207 KB PNG arriving as 320×320 / 12 KB), which would destroy the hidden message. "Sticker" throughout the app is the everyday word for the picture, not a reference to the framework.

// from spec/stealth-v3.md
permKey = PBKDF2-SHA256(pwd, PERM_SALT)
mainKey = PBKDF2-SHA256(pwd, salt)
          // both: 600 000 iterations

STREAM  = salt(16) | marker(4)
        | maskedVer(1) | maskedRsv(1)
        | nonce(12)
        | AES-256-GCM(mainKey,
            len(2) | msg | padding)
        | tag(16)

EMBED   = LSB(blue, STREAM)
          at pixels shuffled by permKey
// no magic bytes, no plaintext length

Live demo

Decode your sticker right here.

A full stealth-v3 implementation in your browser. The image never leaves the page — the bits are read on this tab. Open DevTools → Network and confirm.

Your own sticker not decoding? iMessage sometimes recompresses — see below.

Or pick one of these — each hides something different:

Password for every stealth example: correct horse battery staple

— result appears here

Challenge

Can you find what's hidden?

Built on the public spec — no app, no iPhone needed.

Start

Step by step

What actually happens on decode.

A real stealth-v3 trace on the stealth-hello.png test vector. Every byte below is what the production iOS engine produced. The password is in the open spec — it is not a secret here.

  1. 1

    Sticker → eligible pixels

    128×128 pixels. All 16,384 are fully opaque (alpha = 0xFF), so each contributes one bit. Capacity: 2,048 bytes.

  2. 2

    Password-derived permutation π

    PBKDF2-SHA256 over the password (600,000 iterations) → permKey. From it, an HMAC-counter keystream drives a Fisher–Yates shuffle of [0, N).

    permKey (first 16 bytes) 3b8448c5 30bb162c 284012e5 09b6eb5f
    π[0..7] — where the first 8 logical bits will go [10561, 1462, 14909, 15013, 11089, 2928, 9260, 12068]
  3. 3

    Read the 22-byte header through π

    Walk the permutation, collect the first 22 bytes. They are laid out as salt(16) | marker(4) | masked_version(1) | masked_reserved(1).

    salt (16 bytes) eac76892 9b6426ba 9d888c3d de96c16d
    marker (4 bytes) a5c1 e0f3
    masked version (1 byte) 53
    masked reserved (1 byte) ad
  4. 4

    Per-message keys

    Another PBKDF2 — this time with the salt from the header → mainKey. HKDF-SHA256 over mainKey yields 34 bytes: macKey (32) and mask (2).

    mainKey (first 16 bytes) 9f6ce6e0 f4fe242d 7b2a25a7 e90b61d6
    macKey (first 16 bytes) 455d8201 842b3338 0ac206bf 235a7daa
    mask (2 bytes) 50ad
  5. 5

    Verify the marker

    HMAC-SHA256(macKey, salt || masked_version || masked_reserved)[:4] must equal the marker. Constant-time compare. With the wrong password, computed is just random — that is why "wrong password" is indistinguishable from "not a Stiger sticker".

    computed a5c1 e0f3
    read a5c1 e0f3
    ✓ match

    masked_version XOR mask[0] = 0x03

  6. 6

    AES-256-GCM opens the rest

    The remaining LSB stream is nonce(12) | ciphertext | tag(16). Decrypt with AES-256-GCM using mainKey and nonce.

    nonce bb76 cca9 8c65 16f6 30d6 33c5
    ciphertext 1,998 bytes
    GCM tag b29c 1512 a4c3 f6ad 3b4c 27f3 5ce7 8051
  7. 7

    Parse the plaintext

    Inside the decrypted block: u16-be length | message | random padding to capacity. Length lives inside the cipher, not in the open — so two carriers of the same image look identical regardless of message length.

    length 11
    message "hello world"
    padding 6eec f515 fdc0 f9e5 b516 5477 d79a 63ab … (1,985 bytes of random padding)

Honesty

What Stiger doesn't do.

Privacy tools build trust by being honest about what they don't do. Read this before you trust the app with anything important.

Screenshots break the message.

A photo of a sticker is just a photo. By design — a screenshot of your conversation is not a leak.

iMessage may recompress.

Most of the time it doesn't. Sometimes it does. I test for it; I can't promise it. If it happens, decode fails cleanly.

No forward secrecy.

A leaked password reveals every prior message sent with it. Rotate.

Device compromise is out of scope.

If your phone is unlocked in someone else's hands, no app saves you. Use full-disk encryption and biometric locks.

Without a password, it's not private.

Encryption comes with Pro (free for Russian-speaking users, priced by local income elsewhere). Without it, a sticker carries its message in the open: anyone with Stiger can read it, and a fixed header tells any LSB scanner that Stiger was used. Hidden from people without the app is not the same as encrypted.

It can be spotted, just not read.

Trained steganalysis tools can tell that a sticker carries hidden data, and a forensic look at the chat shows these arrive as image attachments, not native stickers. Who you talk to and when stays visible to Apple, as with any iMessage.

A weak password is a weak lock.

600 000 PBKDF2 iterations slow every guess down, but a 6-character password still falls in hours on commodity GPUs. Use a long passphrase and share it outside iMessage.

Third-party keyboards see your typing.

A keyboard with Full Access can phone home with every keystroke, and Stiger can't block it from inside iMessage. Disable Full Access before composing secrets. Password fields always get the system keyboard.

Maps come from Apple.

A secret that carries a location shows a map preview, and Apple Maps sees the area, from the reader's IP. For a location, that area is most of the secret. Send a place as plain text to keep it away from Apple.

If it's not in your store

There's a simple fix.

Stiger is offered in every App Store region. If it ever disappears from yours, Apple's region switch handles it.

How to switch your store region

Inside the Stiger app

Beyond the iMessage extension.

The iMessage extension is where stickers get sent and read — that's where the encoding happens. The main Stiger app holds the rest: a paranoia guide that walks through every security setting and the tradeoff it makes, and a Store tab where you can pick up more packs. Subscription and the Store are how the project funds itself.

Read what each setting actually protects

Paranoia level: Chill

Default Stiger. Nothing turned on — stickers look ordinary, but anyone with the app can read what's inside.

ChillGuardedParanoid

Drag the handle — this is how the app's own widget works.

Sticker packs

Some people come for the cryptography. Some come for the cactus.

The extension ships with packs — hackers, spies, summer, love notes, memes, midnight. Any sticker in any of them can carry a message.

Built by

Pavel Khudiakov — indie developer.

OneGoodMan.studio. Press inquiries: [email protected].