DEV Community

Cover image for Introducing QR Code Steganography: Because Normal QR Codes Are Too Mainstream
Rolan Lobo
Rolan Lobo

Posted on

Introducing QR Code Steganography: Because Normal QR Codes Are Too Mainstream

The Problem Nobody Knew They Had

You know what's boring? Regular QR codes. You scan them, they take you to a website. Yawn. 😴

You know what's exciting? QR codes that look totally normal to everyone else, but secretly contain hidden messages that only you can read. Spy level: 100. πŸ•΅οΈβ€β™‚οΈ

So I built exactly that into InvisioVault. Because why should images have all the steganography fun?


What Makes This Different?

Most QR code generators can add text. Cool. But that text is in the QR data itself - anyone with a scanner can see it.

InvisioVault's QR codes are double agents. They have:

  • πŸ“± Public data - What normal scanners see (your URL, contact info, whatever)
  • πŸ” Hidden secret - Only visible when scanned with InvisioVault

Scan it with your phone? Goes to your website.

Scan it with InvisioVault? Reveals your secret message.

Same QR code. Two completely different experiences. Magic? No. URL fragments? Yes.


How It Works (The Nerdy Bits)

When you generate a QR code with InvisioVault, we encode it like this:

https://yourwebsite.com/#IVDATA:encrypted_secret_goes_here
Enter fullscreen mode Exit fullscreen mode

Here's the clever part:

  1. Normal QR scanners read the URL and open your browser
  2. Browsers ignore everything after the # (it's a URL fragment)
  3. Your website loads perfectly - no weird data, no errors
  4. InvisioVault reads the full QR data including the fragment
  5. We decrypt and display your hidden message πŸŽ‰

It's like hiding a secret note inside a birthday card, except the birthday card is a QR code and the note is encrypted with AES-256. As one does.


The Journey: A Tale of Trial and Error

Attempt 1: Null Byte Separation

"Let's use \x00 to separate public and private data!"

Result: Some scanners URL-encoded it. URLs looked like website.com%00garbage. Fail. ❌

Attempt 2: LSB Image Steganography

"Hide the secret in the QR code pixels!"

Result: Camera captures recompress images. Pixel data destroyed. Hidden message? Gone. Double fail. ❌❌

Attempt 3: URL Fragments

"What if we just... use URL fragments?"

Result: IT ACTUALLY WORKS. βœ…

Sometimes the simple solution is the right solution. Sometimes you just need to fail twice first.


Live Camera Scanning πŸ“·

But wait, there's more! You can now scan QR codes directly with your webcam. No screenshots, no uploads, just point and scan.

The technical magic:

  • 5-tier progressive camera fallback (works on 95%+ devices)
  • Dual-canvas processing:
    • Original canvas: Preserves color for extraction
    • Enhanced canvas: 2x upscaling + grayscale + 50% contrast boost
  • Adaptive scan intervals (500ms β†’ 2000ms with exponential backoff)
  • MD5-based request caching (60-80% cache hit rate)

Translation: It works fast, on almost any device, and doesn't murder your server. Success! 🎊


Show Me The Goods! πŸ“Έ

Generating a QR Code

Here's what it looks like when you create a secret QR code:

QR generation page

Just a normal-looking QR code generator... or is it? 😏

Scanning & Extracting the Secret

And here's what happens when you scan it with InvisioVault:

QR code scan result

Public data? Check. Hidden secret message? Double check. Mission accomplished! ✨


Why This Is Actually Useful

"Okay cool, but when would I actually use this?"

Glad you asked! Here are some totally-not-made-up scenarios:

  1. Business Cards πŸ“‡

    • Public: Your LinkedIn profile
    • Secret: Your actual phone number (for select people who scan it right)
  2. Event Tickets 🎫

    • Public: Event website
    • Secret: VIP access code or exclusive content link
  3. Product Packaging πŸ“¦

    • Public: Product information
    • Secret: Warranty details or customer support portal
  4. Marketing Materials πŸ“°

    • Public: Standard landing page
    • Secret: Special discount code for InvisioVault users
  5. Just Because You Can πŸŽ‰

    • Public: Rick Roll link
    • Secret: Actual content you wanted to share
    • (Okay this one might be real)

Performance Stats πŸ“Š

Because numbers make everything more credible:

Metric Result
QR Detection Rate 80%+ in good lighting
Device Compatibility 95%+
Backend Load Reduction 60-80% (thanks to caching)
Normal Scanner Compatibility 100% (they just ignore the secret)
Times I Thought This Wouldn't Work 47
Times I Was Wrong 1 (this time it worked!)

The Code Journey

This feature went through more iterations than I'd like to admit:

- Attempt 1: Data encoding with null bytes
+ Attempt 2: LSB pixel steganography
+ Attempt 3: URL fragment encoding βœ“
Enter fullscreen mode Exit fullscreen mode

Shoutout to:

  • Segno for QR generation
  • Pyzbar for QR scanning
  • URL fragments for existing and being perfect for this
  • Coffee for existing

Try It Yourself!

Head over to InvisioVault and give it a spin!

  1. Generate a QR code with a hidden message
  2. Scan it with your phone - see the public data
  3. Scan it with InvisioVault - see the secret
  4. Feel like a spy
  5. Repeat until you've hidden secrets everywhere

What's Next?

Some ideas I'm considering (read: may or may not implement):

  • 🎨 More QR customization options (logos, colors, patterns)
  • πŸ“Š Analytics to see who scanned your QR codes
  • πŸ”— QR code chaining (scan one, get led to another, treasure hunt style!)
  • 🎭 Multiple hidden messages in one QR (because why not?)

Final Thoughts

Building this feature taught me several things:

  1. The simple solution is often hidden behind two complicated ones
  2. URL fragments are more useful than you think
  3. Camera APIs are surprisingly well-supported now
  4. LSB steganography is fragile and I should stop trying to make it work for everything

If you made it this far, congrats! You're either really interested in steganography, procrastinating on actual work, or both. Either way, thanks for reading! πŸŽ‰

Now go forth and hide secrets in QR codes. The world is your oyster. Or QR code. Same thing.


Technical Details (For the Curious)

If you want to dive deep into how this works:

Encryption:

  • AES-256-CBC with PBKDF2 key derivation
  • 100,000 iterations (industry standard)
  • Random 16-byte salt and IV for each generation

QR Format:

{public_data}#IVDATA:{base64_encrypted_secret}
Enter fullscreen mode Exit fullscreen mode

Camera Processing:

  • MediaStream API for webcam access
  • Canvas API for frame capture and enhancement
  • Dual-canvas approach for quality preservation
  • Real-time QR detection with adaptive intervals

Performance Optimizations:

  • MD5 hashing for request deduplication
  • In-memory caching with 1-second TTL
  • Exponential backoff to reduce unnecessary processing
  • Progressive camera configuration fallback

Made with πŸ’œ by Rolan

P.S. - If you find any bugs, they're not bugs, they're undocumented features. But please tell me anyway. πŸ˜…


Share Your Creations!

If you create something cool with this feature, tag me! I'd love to see what creative uses people come up with for hidden QR messages.

GitHub: @Mrtracker-new

Email: rolanlobo901@gmail.com

Happy hiding! 🎭✨

Top comments (0)