Steganography に PNG が必須な理由 — 非可逆 vs 可逆圧縮
JPEG の非可逆圧縮が LSB データを破壊する理由と、PNG の可逆圧縮が不可欠な理由を解説。DCT、量子化、非可逆フォーマットが埋め込みビットを壊す仕組みを説明します。
詳細な説明
可逆 vs 非可逆 — フォーマットが重要な理由
LSB steganography の最も重要なルールは「出力は必ず可逆圧縮フォーマットで保存する」ことです。PNG は使えますが、JPEG は使えません。その理由を理解するには、各フォーマットのピクセルデータの保存方法を知る必要があります。
PNG のデータ保存方式
PNG は DEFLATE 圧縮 を使用しており、完全に可逆です。展開後のピクセルデータは元のデータとビット単位で同一です。つまり、埋め込み時に慎重に設定した LSB は、画像の保存と再読み込みの際に完全に保持されます。
元のピクセル → DEFLATE 圧縮 → PNG ファイル → DEFLATE 展開 → 同一のピクセル ✓
JPEG のデータ保存方式
JPEG は非可逆パイプラインを使用します:
- 色空間変換 — RGB を YCbCr に変換し、色差チャンネルをダウンサンプリング。
- DCT(離散コサイン変換) — 8×8 ピクセルブロックを周波数係数に変換。
- 量子化 — 係数を品質に応じた行列で除算し、丸め処理。このステップが破壊的で不可逆です。
- エントロピー符号化 — 量子化された係数をハフマン符号化。
量子化ステップで周波数係数が丸められるため、逆変換でピクセル値に戻すと元の値と異なります。この差は表示上は許容範囲ですが、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 画像を共有すると隠しメッセージが破壊される理由を理解したいユーザー向け。