This is demo of Steg (GitHub, npm), steganography library that allows to encrypt and hide arbitrary data inside png images.

  • Encodes data using least significant bits of PNG pixels.
  • Only PNGs are supported, JPGs cannot be used - every time you save them, they can get re-encoded and some data would be lost, which is a no-go for steganography
  • However, you could feed JPG to the encryption form, and it would be converted to PNG
  • Encrypts hidden data and its metadata with AES-GCM-256 + Scrypt. LSB bitsTaken are not encrypted, so it is slightly easier to understand something is hidden inside .png, however, since we are using encryption + padding, it's not trivial to understand what's exactly is inside.
  • Experimental. Use at your own risk.

Encrypt file and hide it inside image


Extract file from image and decrypt it

Technical information

Algorithm

  1. Calculate the capacity of png image at given `bitsTaken` and save it into `capacity`
  2. Create a flat byte array structure with 5 fields ABCDE, that represents file and its metadata:
    • A `bytes 0..1` name length, 4GB max
    • B `bytes 1..[1+name length]` name, 32 bytes max
    • C `bytes B..B+4` file size length, 4GB max
    • D `bytes C..[C+file length]` file contents
    • E `bytes D..end` padding filled with zeros - zeros are okay, since we encrypt them
  3. Encrypt ABCDE under given AES key with AES-GCM-256.
    • IV `bytes 0..12` taken from CSPRNG
    • ciphertext `bytes 12..(end-16)` encrypted ABCD
    • auth tag `bytes end-16..end` GCM authentication tag

The web app

  • We're using Scrypt; with N=2^19, r=8, p=1 and salt="steg-file"
  • If CSPRNG is not available, the app would crash
  • AES GCM Authentication Tag is calculated and verified properly