Steganography に PNG が必須な理由 — 非可逆 vs 可逆圧縮

JPEG の非可逆圧縮が LSB データを破壊する理由と、PNG の可逆圧縮が不可欠な理由を解説。DCT、量子化、非可逆フォーマットが埋め込みビットを壊す仕組みを説明します。

Basics

詳細な説明

可逆 vs 非可逆 — フォーマットが重要な理由

LSB steganography の最も重要なルールは「出力は必ず可逆圧縮フォーマットで保存する」ことです。PNG は使えますが、JPEG は使えません。その理由を理解するには、各フォーマットのピクセルデータの保存方法を知る必要があります。

PNG のデータ保存方式

PNG は DEFLATE 圧縮 を使用しており、完全に可逆です。展開後のピクセルデータは元のデータとビット単位で同一です。つまり、埋め込み時に慎重に設定した LSB は、画像の保存と再読み込みの際に完全に保持されます。

元のピクセル → DEFLATE 圧縮 → PNG ファイル → DEFLATE 展開 → 同一のピクセル ✓

JPEG のデータ保存方式

JPEG は非可逆パイプラインを使用します:

  1. 色空間変換 — RGB を YCbCr に変換し、色差チャンネルをダウンサンプリング。
  2. DCT(離散コサイン変換) — 8×8 ピクセルブロックを周波数係数に変換。
  3. 量子化 — 係数を品質に応じた行列で除算し、丸め処理。このステップが破壊的で不可逆です。
  4. エントロピー符号化 — 量子化された係数をハフマン符号化。

量子化ステップで周波数係数が丸められるため、逆変換でピクセル値に戻すと元の値と異なります。この差は表示上は許容範囲ですが、LSB を完全に破壊します

具体例

メッセージビット 1 をピクセルの赤チャンネルに埋め込み、値を 148 から 149 に変更した場合:

JPEG 圧縮前: R = 149(埋め込み値, LSB = 1)✓
JPEG 圧縮後: R = 146(量子化でずれた, LSB = 0)✗

メッセージビットは失われます。画像全体では、JPEG 圧縮は約 25〜50% の LSB を反転させ、抽出されたメッセージは無意味なデータになります。

品質 100 の JPEG はどうか?

最高品質設定でも、JPEG は DCT と量子化を適用します(丸め誤差は最小ですがゼロではありません)。品質 100 は「可逆」ではなく「最も劣化が少ない」という意味です。LSB データはやはり壊れます。

その他の可逆フォーマット

PNG 以外にも LSB データを保持できるフォーマットがあります:

  • BMP — 非圧縮のため LSB は保持されるが、ファイルサイズが非常に大きい。
  • TIFF(可逆圧縮モード) — LZW または ZIP 圧縮を使用。
  • WebP(可逆モード) — Google のフォーマットで、ピクセル値を正確に保持する可逆モードをサポート。

このツールが PNG を必須とする理由

このツールは HTML5 Canvas API を使用し、canvas.toDataURL('image/png') で PNG を出力します。アップロードされた画像のピクセルを ImageData 配列に読み込み、ツールが LSB を変更し、結果を PNG としてエクスポートすることで、ビットパーフェクトな出力を保証します。

ユースケース

JPEG をアップロードした際にツールが PNG に変換する理由を知りたいユーザーや、SNS(JPEG に再圧縮するプラットフォーム)で stego 画像を共有すると隠しメッセージが破壊される理由を理解したいユーザー向け。

試してみる — Invisible Watermark

フルツールを開く