WAV Steganography Hider
Hide text or files inside WAV audio using LSB in PCM samples, PRNG sample selection, RIFF chunk injection, or spectrogram encoding. DeepSound-signature and WavSteg-style modes, optional AES-256-GCM. Processed in your browser, not uploaded.
Before uploading: share the output only as a file attachment (email, cloud storage, Discord file). Services that re-encode audio to a lossy format (YouTube, streaming services, most messaging apps) can change sample values and corrupt LSB data or prevent its recovery; individual services have not been tested.
Try demo — embed a message instantly
Loads a short sample WAV — no upload needed
Drop a WAV file here
PCM integer or IEEE float — MP3/ADPCM not supported
Processed in your browser
Your audio is processed in this browser tab and not sent to a server. Usage statistics may record which options were used, never your audio.
How to Hide Data in a WAV Audio File (5 steps)
- Upload a WAV file: PCM integer (8, 16, 24 or 32-bit) or 32-bit float, mono or stereo. The result is always a new 16-bit PCM WAV.
- Type your secret message or choose a file to hide. A hidden file keeps its name (except in the stego-lsb layout).
- Quick mode uses 1-bit LSB. Standard also offers PRNG sample selection, 1 to 3 bits per sample and left, right or both channels. Forensic adds RIFF Chunk Injection, Spectrogram Encoding, the DeepSound marker, the stego-lsb layout and Reed-Solomon.
- Optionally add a passphrase to encrypt with AES-256-GCM (not available for Spectrogram Encoding or the stego-lsb layout).
- Click Embed. The tool reads the message back from its own result and only offers the file if it matches.
WAV Steganography Methods — What This Tool Handles
| Method | Mechanism | Capacity | Best For |
|---|---|---|---|
| LSB in PCM Samples | Replaces the lowest 1, 2 or 3 bits of 16-bit samples, in order, after a 160-bit header | (samples − 160) × bits ÷ 8 bytes | Default. Each sample moves by at most 1, 3 or 7. Measured 59 to 90 dB signal-to-noise at 1 bit |
| PRNG Sample Selection | Same bits, but at passphrase-seeded sample positions instead of in order | Same as LSB | Scatters the embedding positions instead of writing bits in order. This does not encrypt the payload or establish resistance to statistical detection. Without a passphrase the seed is 0, so positions are fixed and public. Detection resistance not measured |
| RIFF Chunk Injection | Payload in a custom 'steg' chunk before the audio data; the 160-bit header still sits in the first samples | No separate limit from this method; file-size and browser-memory limits still apply | Any RIFF chunk lister shows it; any program that rewrites the file drops it (lost after a plain WAV re-export in our tests) |
| Spectrogram Encoding | Appends tone bursts: 8 tones from 4,000 to 8,000 Hz, one bit per 20 ms, so 0.16 s per stored byte | Audio length added = 0.16 s × stored bytes | Visible in Audacity or Sonic Visualiser. Never encrypted. Needs a sample rate of 18,000 Hz or more |
| stego-lsb layout | The real stego-lsb (WavSteg) layout: bit 8 of each sample, MSB-first, from sample 0, no header | samples ÷ 8 bytes | Interoperates with the real program in both directions (tested). 16-bit WAV only. Changes samples by 256, far more noise than LSB |
What Changes in the File
A WAV file is a RIFF container: a 'fmt ' chunk that describes the audio, a 'data' chunk of samples, and optional chunks for metadata. This tool reads your file, converts every sample to a 16-bit number, embeds the message, and writes a brand-new 16-bit PCM WAV. Nothing from the original container is kept except channels, sample rate and the samples, and 8-bit, 24-bit and 32-bit inputs lose resolution in the conversion (24-bit input becomes 16-bit, reducing the sample-data size by one third for the same number of samples; the total output size also depends on the rebuilt container and any added chunks).
Apart from the stego-lsb layout, every method first writes a 160-bit header into the lowest bit of the first 160 samples, so even RIFF Chunk Injection and Spectrogram Encoding change up to 160 samples by 1. In our test of RIFF Chunk Injection on a stereo file 80 of 8,000 samples changed. The header is what lets the Extractor find the method, bit depth, channels, password flag and length without any settings.
Choosing a Method
LSB in PCM Samples is the default. In our seven-file tests, LSB and PRNG data survived a plain lossless WAV re-export, Spectrogram tones stayed readable when the block could be located, and RIFF Chunk Injection did not survive it. PRNG Sample Selection stores the same number of bits at positions chosen from your passphrase; with no passphrase the seed is 0, so the positions are fixed and public. Both write 1, 2 or 3 bits per sample, so at 3 bits a sample can move by up to 7 out of 32,768.
RIFF Chunk Injection is not steganography in the strict sense: the payload sits in its own chunk that any chunk viewer lists, and any editor that rewrites the file removes it. In our tests it did not survive even a plain WAV re-export. Spectrogram Encoding is meant to be seen: it appends audible tone bursts (this adds 0.16 seconds per stored byte), which is the classic CTF trick of a message visible in a spectrogram. The stego-lsb layout exists to exchange files with the real stego-lsb program.
How Each Method Stores the Data
The payload is first optionally deflated, then optionally AES-256-GCM encrypted, then optionally wrapped with Reed-Solomon parity. The 20-byte header is: the letters WAVS, a version byte (1), the method, the bit depth, the channel mode (left, right or both), an encryption flag, a compression flag, the Reed-Solomon level (0, 10, 20 or 30), a compatibility code, the stored payload length (4 bytes, little-endian) and a CRC-32 of the first 16 bytes. The CRC detects accidental change; it does not authenticate anything.
LSB writes the payload bits least-significant-bit first into the lowest bits of consecutive samples starting at sample 160. PRNG does the same at positions drawn with a Mulberry32 generator seeded from the passphrase (FNV-1a hash), keeping the positions in ascending order; if the generator cannot find enough distinct positions near full capacity, the lowest unused positions fill the rest. RIFF Chunk Injection writes the stored bytes into a 'steg' chunk placed after 'fmt ' and before 'data'. Spectrogram Encoding appends the tone block described above. The stego-lsb layout skips the header and the stored-bytes pipeline entirely and writes the message most-significant-bit first into bit 8 of each sample from the first sample.
Capacity: What Fits
LSB and PRNG hold (usable samples − 160) × bits ÷ 8 bytes. 'Usable samples' is every sample for both channels, or every other sample for left-only or right-only stereo. The capacity bar subtracts what is stored beyond your text: 48 bytes for a password, 2 bytes plus the name for a hidden file, and Reed-Solomon parity; deflate is not predicted, the encoder checks the compressed size. The figure is tested against the real encoder at the exact limit for every method, bit depth, password and Reed-Solomon combination, with the written file decoded independently. One byte more is refused with a message.
Spectrogram Encoding has no fixed capacity; it adds 0.16 seconds of audio per stored byte, so a 1,000-byte message adds 160 seconds. RIFF Chunk Injection adds no separate limit of its own; file-size and browser-memory limits still apply. The stego-lsb layout holds samples ÷ 8 bytes.
How Strong Is the Encryption?
If you set a password, the payload is encrypted before it is hidden, in your browser, with the Web Crypto API. The cipher is AES-256 in GCM mode. The 256-bit key is derived from your password with PBKDF2 using HMAC-SHA-256 and 100,000 iterations. Every encryption generates a fresh random 16-byte salt and a fresh random 12-byte IV with the browser's cryptographically secure random generator (crypto.getRandomValues), so encrypting the same message twice gives different bytes. The stored layout is a 4-byte length, the salt, the IV, then the ciphertext followed by a 16-byte authentication tag — 48 bytes added in total. The tag means a wrong password, or any change to the ciphertext, makes decryption fail instead of returning garbage.
These are standard, widely used primitives, but this implementation has not had an independent audit, and using them does not make the system unbreakable. Their limits matter. Anyone who finds the hidden data can copy the ciphertext and try passwords against it offline, so your password is the real defence: use a long random passphrase, not a word or a date. The key derivation uses 100,000 PBKDF2-HMAC-SHA-256 iterations. This is below OWASP's commonly cited 600,000-iteration recommendation for password storage. That recommendation is not a direct requirement for this file-encryption format, but the lower count makes a strong, unique password especially important. The iteration count is fixed in the code and is not written into the file, so raising it requires a new, versioned format so that files already made can still be opened.
Encryption hides what the data says, not that it exists, and it does not hide the length: AES-GCM ciphertext is the same length as the plaintext, and the encrypted layout adds a fixed 48 bytes of overhead: its own 4-byte length field, the salt, the IV and the authentication tag, separate from any length or framing the tool puts around it. No padding is added. There is no key file and no way to recover a forgotten password. We have not measured key-derivation time on phones or older devices, so very large batches or slow devices may take noticeably longer per file. The tool is intended for educational and personal use; do not rely on it as the only protection for sensitive information, or against a well-resourced adversary.
Verification, Reed-Solomon and Other Forensic Options
After embedding, the tool reads the message back from the samples it just produced and compares it with your payload. If they differ no file is produced. This check works on the samples in memory before the WAV is written, so it confirms the embedding, not the final file on disk.
Reed-Solomon (RS-10, RS-20, RS-30) adds parity so that scattered changed bytes in the stored data can be repaired. It cannot repair a file that was re-encoded by a lossy codec, because that changes almost every sample. It is switched off in the stego-lsb layout, which has no place for it.
Capacity Examples (computed by the tool's own function)
Largest message in bytes with no password, no compression and no Reed-Solomon, for one minute of 44.1 kHz audio.
| Layout | Samples | Bits per sample | Largest message |
|---|---|---|---|
| Stereo, both channels, LSB or PRNG | 5,292,000 | 1 | 661,480 B |
| Stereo, both channels, LSB or PRNG | 5,292,000 | 2 | 1,322,960 B |
| Stereo, both channels, LSB or PRNG | 5,292,000 | 3 | 1,984,440 B |
| Stereo, left channel only | 2,646,000 usable | 1 | 330,730 B |
| Mono | 2,646,000 | 1 | 330,730 B |
| Stereo, stego-lsb layout | 5,292,000 | 1 | 661,500 B |
Measured Signal-to-Noise of the Embedded File
Signal-to-noise ratio of the output against the original samples, 7 real files (one speech clip and five macOS system sounds, one of them in mono and in stereo; 44.1 kHz 16-bit), random payload filling 5%, 25% and 90% of capacity. Higher is a smaller change. Whether a change is audible depends on the recording and the listener and was not tested.
| Method | 5% full | 25% full | 90% full |
|---|---|---|---|
| LSB 1-bit | 71.6 to 90.4 dB | 64.7 to 83.4 dB | 59.1 to 77.8 dB |
| LSB 2-bit | 64.5 to 83.4 dB | 57.6 to 76.4 dB | 51.7 to 70.8 dB |
| LSB 3-bit | 58.5 to 77.1 dB | 51.4 to 70.2 dB | 45.0 to 64.6 dB |
| PRNG 1-bit | 71.5 to 90.3 dB | 64.6 to 83.4 dB | 59.1 to 77.8 dB |
| stego-lsb layout | 23.5 to 42.2 dB | 16.5 to 35.2 dB | 11.0 to 29.6 dB |
What Survives Re-Encoding (7 files)
A 29-byte message embedded with each method, then re-encoded with the ffmpeg build this site ships (libmp3lame, aac, libvorbis) and decoded back to 16-bit WAV with the codec delay removed. 'Header read' means the Extractor's automatic detection returned the message. Other encoders, platforms and players were not tested.
| Method | WAV re-export | MP3 320k | MP3 128k | AAC 128k | Vorbis q5 |
|---|---|---|---|---|---|
| LSB | 7 of 7 | 1 of 7 | 0 of 7 | 0 of 7 | 0 of 7 |
| PRNG | 7 of 7 | 0 of 7 | 0 of 7 | 0 of 7 | 0 of 7 |
| RIFF Chunk Injection | 0 of 7 | 0 of 7 | 0 of 7 | 0 of 7 | 0 of 7 |
| Spectrogram: header read | 7 of 7 | 1 of 7 | 0 of 7 | 0 of 7 | 0 of 7 |
| Spectrogram: tones readable if you know where the block starts and how long it is | 7 of 7 | 7 of 7 | 7 of 7 | 2 of 7 | 7 of 7 |
Examples
Input: A 30-second mono 44.1 kHz WAV and a 2,000-byte message that deflate cannot shrink, 1-bit LSB, no password
Result: Capacity 165,355 bytes; the message fits. At most 16,160 sample positions are used (16,000 message bits plus the 160-bit header), and no sample changes by more than 1 (a sample whose lowest bit already matches is not changed).
Meaning: Roughly 1% of the capacity is used. The output is a new 16-bit WAV; the original file's metadata chunks are not in it.
Input: A 10-byte message with Spectrogram Encoding on a 48 kHz file
Result: 1.6 seconds of tone bursts (10 × 0.16 s) are appended after the audio; the first 160 samples get the header bits.
Meaning: The block is easy to see in a spectrogram viewer. The slot length follows the file's own sample rate; round trips were tested at 18, 22.05, 24, 32, 44.056, 44.1, 48 and 96 kHz in mono and stereo.
Input: A 16-bit stereo WAV hidden with the stego-lsb layout, then recovered with 'stego-lsb recover' for the same number of bytes
Result: The real program returns the message exactly. Our Extractor lists the same text as its 'stego-lsb (WavSteg) layout' candidate.
Meaning: Both directions were run against the real program on mono and stereo files; the layout changes bit 8 of each sample, which is a much bigger change than plain LSB.
How the WAV Hider Works
Read and normalise
The WAV is parsed in a Web Worker. 8-bit, 24-bit and 32-bit samples are converted to 16-bit numbers and extra chunks are noted but not kept.
Prepare the payload
Your message is optionally deflated, optionally encrypted with AES-256-GCM (key from your passphrase with PBKDF2) and optionally given Reed-Solomon parity. The result is the stored payload.
Check capacity
The stored size is compared with the method's capacity. If it does not fit, nothing is written and you get the exact numbers.
Write header and payload
A 160-bit header goes into the lowest bits of the first samples, then the payload goes into samples, a 'steg' chunk or an appended tone block depending on the method.
Read it back
The tool decodes its own samples and compares the result with your message. If they differ it stops with an error instead of offering the file.
Write a new WAV
A new 16-bit PCM WAV is assembled (plus the DeepSound marker if you chose it) and offered for download.
What the results mean
| Result | What it means | What to do |
|---|---|---|
| Embedding Complete, with "Auto-verify: N bytes extracted successfully" | The message was recovered from the samples the tool produced. | Download the file and send it as a file; do not convert it. |
| Payload too large | The stored payload (message plus 48 bytes for a password plus parity) is bigger than the method's capacity. | Shorten the message, use a lower fill, 2 or 3 bits, both channels, or another method. |
| The payload was embedded but reading it back did not return your message | The result failed the tool's own check, so no file was produced. | Try a smaller message or another method; report it if it happens with an ordinary file. |
| Spectrogram Encoding needs a sample rate of at least 18000 Hz | The 4 to 8 kHz tones cannot be represented in a low-rate file. | Use LSB or RIFF Chunk Injection, or resample the audio first. |
| stego-lsb compatibility needs a 16-bit PCM WAV | The real program uses different bytes for other sample sizes. | Convert the file to 16-bit PCM first. |
Limitations
- The output is always a new 16-bit PCM WAV: input metadata chunks are dropped and other bit depths are converted, which changes the audio beyond the hidden bits.
- LSB and PRNG data survived copying the file and a plain lossless WAV re-export in our seven-file tests. After lossy conversion the LSB header was not detected in 27 of 28 attempts; Spectrogram tones stayed readable in some lossy outputs when the block's start and length were known; RIFF Chunk Injection did not survive even a WAV re-export. These results apply to the tested files and codecs only.
- Signal-to-noise and re-encoding survival were measured on seven short files (one speech clip and five system sounds, one of them in both mono and stereo). Audibility was not tested with listeners, and no statistical detector was run against these methods.
- Spectrogram Encoding is visible by design and never encrypted; the Extractor reads it only through the header, so after a lossy conversion you must locate the tone block and its length yourself.
- Individual websites, messaging apps and audio editors were not tested.
- Key derivation time on phones was not measured.
Privacy
The WAV is processed in your browser tab with a Web Worker and the Web Crypto API; it is not uploaded. Usage statistics may record which options were used, such as the method, never the audio, the message or the passphrase. The hosting provider keeps ordinary request logs for page loads.
Which Tool Next?
- WAV Steganography Extractor — read a message back out of a WAV, including real stego-lsb files.
- Audio Steganography Hider — Phase Coding and Spread Spectrum, which in that tool's tests (three carriers, one short message) were read back after the MP3 and AAC conversions tried there; Spread Spectrum failed on speech after AAC 128.
- MP3 Steganography Embedder — for MP3 files.
- Steganography Detector — statistical checks on the file.
Frequently Asked Questions
Why is WAV better suited for steganography than MP3?
WAV stores raw PCM samples as exact integers, so a changed low bit stays changed for as long as the file is only copied. MP3, AAC and Vorbis rebuild the samples from a lossy model: in our tests the LSB header was lost in 27 of 28 lossy attempts (seven recordings, four codecs; one 320 kbps MP3 kept it). A plain WAV re-export through ffmpeg kept LSB and PRNG data in 7 of 7 clips.
Does the output keep my file's other data?
No. The tool writes a new 16-bit PCM WAV with a minimal fmt chunk, any extra chunk it adds, and the samples. Metadata chunks of the input (LIST, cue, bext and so on) are not copied. An 8-bit, 24-bit or float input is converted to 16-bit, which changes the audio by more than the hidden bits, and for 24-bit input the sample data is a third smaller (the total file size also depends on the rebuilt container).
Does a hidden file keep its name?
Yes, for the LSB, PRNG, RIFF Chunk Injection and Spectrogram methods: the name is stored inside the hidden data (before compression and encryption, so a passphrase protects it too) and the Extractor offers the download under that name. It costs 2 bytes plus the name's UTF-8 length, and names longer than 255 bytes are cut. Typed text stores no name, and the stego-lsb layout has no header to mark one.
What does DeepSound mode do?
It adds a LIST/INFO chunk reading INFOSOFTWARE=DeepSound 2.0 to the output, and the Extractor looks for that text. The payload is still stored in this tool's own layout, so DeepSound itself cannot open the file. It is a marker for CTF challenges, not compatibility with DeepSound's format.
Is the stego-lsb mode compatible with the real program?
Yes, and this was checked with the real stego-lsb 1.7.2 in both directions: its recover command returns our output and our Extractor reads its output, byte for byte, on mono and stereo 16-bit files. The layout is not what its name suggests: it changes bit 8 of each sample (a change of 256), writes the message most-significant-bit first, and needs you to know the length when using the real program.
How does Spectrogram Encoding work, and why isn't it encrypted?
Each payload byte becomes eight 20 ms slots, one per bit. A set bit plays its tone (bit 0 = 4,000 Hz up to bit 7 = 8,000 Hz in equal steps), a clear bit is silence. The block is appended after your audio, so a message of N stored bytes adds 0.16 × N seconds. Opening the file in a spectrogram viewer shows it. The tones map payload bits directly, so this implementation does not encrypt the payload in this mode. The password option is disabled and the tone pattern can reveal the encoded data. Do not use Spectrogram Encoding for a confidential message.
Is my audio uploaded anywhere?
No. Encoding runs in your browser tab (a Web Worker and the Web Crypto API); the audio is not sent to a server. Usage statistics may record which options were used, never your audio or passphrase.
Related Tools
WAV Steganography Extractor
Extract hidden text or files from WAV audio. WAVSTEG auto-detect, RIFF chunk inspector, DeepSound signature detection, spectrogram analysis, 13-setting ranked guess, CTF flag detector. Processed in your browser, not uploaded.
Audio Steganography Hider
Hide text or files in WAV audio (an MP3 is converted to WAV first) with AES-256 encryption, Reed-Solomon error correction, a capacity meter and an SNR quality report. Processed in your browser.
Steganography Capacity Calculator
Calculate exact hidden-payload capacity for PNG, BMP, WebP, WAV, FLAC, AIFF and more — plus PSNR and detection risk, all client-side. Links to the right specialist hider/extractor for your file type.