最終更新:

ステガノグラフィ - テキストに秘密のメッセージを隠す技術と文字数

約 7 分で読めます

この段落には秘密のメッセージが隠されています - と言われたら、あなたはどこを探しますか? 各文の頭文字? 特定の文字の間隔? それとも、目に見えない文字が埋め込まれている可能性? ステガノグラフィ (steganography) は、メッセージの存在そのものを隠す技術です。暗号化が「読めない形にする」技術なら、ステガノグラフィは「そこにメッセージがあること自体を気づかせない」技術。そしてこの技術は、文字数カウントという単純な行為で検出できることがあります。

古代から続く「隠す」技術

ステガノグラフィの歴史は紀元前 5 世紀のギリシャにまで遡ります。歴史家ヘロドトスが記録した有名なエピソードでは、ペルシア帝国の侵攻を警告するために、奴隷の頭を剃って頭皮にメッセージを刺青し、髪が伸びてから使者として送り出したとされています。メッセージの到着までに数週間かかるという、究極の低帯域通信です。

中世ヨーロッパでは、不可視インク (レモン汁、牛乳、尿など) を使った秘密通信が広く行われました。第二次世界大戦中には、ドイツのスパイがマイクロドット技術 (文書を写真で極小に縮小してピリオドに偽装する) を使用しました。1 つのピリオドに 1 ページ分のテキストを隠せるこの技術は、FBI 長官のフーバーが「敵のスパイ活動における最大の進歩」と呼んだほどです。

テキストベースのステガノグラフィ手法

デジタル時代のテキストステガノグラフィには、いくつかの代表的な手法があります。

アクロスティック - 頭文字に隠すメッセージ

アクロスティック (acrostic) は、各行や各文の頭文字を繋げると秘密のメッセージが現れる手法です。最も古典的なテキストステガノグラフィであり、詩や歌詞に古くから使われてきました。

有名な例として、2003 年にカリフォルニア州の検事総長ビル・ロッキャーが辞任する州議会議員に送った手紙があります。各段落の頭文字を繋げると「I FUCK YOU」と読めることが発覚し、大きなスキャンダルになりました。アクロスティックは文字数を増やさずにメッセージを埋め込めますが、意図的に探せば容易に発見できるという弱点があります。

空白文字の操作

単語間のスペースの数を操作してビット情報を埋め込む手法です。スペース 1 つを「0」、スペース 2 つを「1」として、バイナリデータをエンコードします。人間の目にはスペースの微妙な違いは気づきにくいですが、文字数カウントツールを使えば「見た目の単語数に対してスペースが多すぎる」ことで検出できます。

ゼロ幅文字ステガノグラフィ - 見えない文字の世界

現代のテキストステガノグラフィで最も強力な手法が、ゼロ幅の不可視文字を利用する方法です。Unicode には、画面上に表示されないが文字データとしては存在する「ゼロ幅文字」が複数定義されています。

Unicode コードポイント名称本来の用途ステガノグラフィでの役割
U+200BZero Width Space改行可能位置の指定ビット「0」を表現
U+200CZero Width Non-Joiner合字の抑制ビット「1」を表現
U+200DZero Width Joiner合字の促進追加のビット値
U+FEFFZero Width No-Break Space (BOM)バイト順マーク区切り文字

U+200B と U+200C の 2 種類のゼロ幅文字を使えば、2 値 (0 と 1) で 1 ビットを表現できます。8 つのゼロ幅文字で 1 バイト、つまり 1 つの ASCII 文字を隠せます。「Hello」という 5 文字のメッセージを隠すには、40 個のゼロ幅文字が必要です。

この 40 個のゼロ幅文字を通常のテキストの単語間に分散して埋め込めば、見た目は全く変わりません。しかし、文字数カウントツールで「見た目の文字数」と「実際の文字数 (バイト数)」を比較すると、不自然な差異が検出されます。Unicode の基礎知識を理解していれば、この差異の原因がゼロ幅文字であることを特定できます。

ゼロ幅文字ステガノグラフィの実装例

具体的な埋め込みの流れを見てみましょう。秘密メッセージ「Hi」を通常のテキスト「Good morning」に埋め込む場合を考えます。

「H」の ASCII コードは 72、2 進数で 01001000 です。「i」は 105、2 進数で 01101001 です。0 を U+200B (ゼロ幅スペース)、1 を U+200C (ゼロ幅非接合子) に変換すると、16 個のゼロ幅文字列が生成されます。

この 16 個のゼロ幅文字を「Good」と「morning」の間に挿入します。見た目は「Good morning」のままですが、実際のデータには 16 個の不可視文字が含まれています。テキストエディタで文字数を数えると 12 文字ですが、プログラムで Unicode コードポイント数を数えると 28 文字になります。この差の 16 文字が、隠されたメッセージの正体です。

より高度な実装では、3 種類以上のゼロ幅文字を使って 3 値以上のエンコーディングを行い、同じメッセージをより少ないゼロ幅文字で表現します。U+200B、U+200C、U+200D の 3 種類を使えば、1 文字あたり約 1.58 ビット (log₂3) の情報を格納でき、8 ビットの ASCII 文字を約 5 個のゼロ幅文字で表現できます。

ホモグリフ攻撃 - 見た目が同じ別の文字

ホモグリフ (homoglyph) とは、見た目がほぼ同一だが Unicode のコードポイントが異なる文字のことです。例えば、ラテン文字の「a」(U+0061) とキリル文字の「а」(U+0430) は、多くのフォントで全く同じ見た目になります。

ラテン文字コードポイントキリル文字コードポイント見た目の違い
aU+0061аU+0430ほぼ同一
eU+0065еU+0435ほぼ同一
oU+006FоU+043Eほぼ同一
pU+0070рU+0440ほぼ同一
cU+0063сU+0441ほぼ同一

この特性を悪用したのがホモグリフ攻撃です。フィッシングサイトの URL で「apple.com」の「a」をキリル文字の「а」に置き換えると、見た目は同じですが全く別のドメインに誘導されます。ステガノグラフィの文脈では、テキスト中の特定の文字をホモグリフに置き換えることで、ビット情報を埋め込むことができます。

ホモグリフの検出には、文字列の各文字の Unicode コードポイントを確認する必要があります。パスワードの文字数と安全性で触れたように、見た目が同じでもバイト列が異なるケースは、セキュリティ上の重大なリスクになります。

ホモグリフ攻撃の対策として、主要なブラウザは IDN (国際化ドメイン名) の表示に制限を設けています。ドメイン名に複数のスクリプト (ラテン文字とキリル文字など) が混在している場合、ブラウザはドメイン名を Punycode (xn-- で始まるエンコード形式) で表示し、ユーザーに偽サイトであることを警告します。Chrome は 2017 年のバージョン 58 からこの対策を導入しました。

テキストの透かし (ウォーターマーク) 技術

ステガノグラフィの応用として、テキストの透かし (digital watermarking) 技術があります。画像や動画の透かしは広く知られていますが、テキストにも透かしを埋め込む技術が存在します。

透かし手法原理検出方法耐性
ゼロ幅文字埋め込み不可視文字でビット情報を格納文字数カウントコピー&ペーストで消える場合がある
同義語置換「大きい」→「巨大な」のように同義語で置換原文との比較テキスト編集に強い
構文変換能動態 → 受動態のように構文を変換原文との比較テキスト編集に強い
空白操作スペースやタブの数を操作空白文字の統計分析フォーマット変更で消える

同義語置換による透かしは、テキストの意味を変えずにビット情報を埋め込む手法です。例えば、「大きい」を「巨大な」に置き換えることで 1 ビットの情報を表現します。この手法は文字数が変わる可能性がありますが、テキストの編集やコピー&ペーストに対して耐性があります。

暗号化とステガノグラフィの違い

暗号化 (encryption) とステガノグラフィは、しばしば混同されますが、根本的に異なる技術です。

特性暗号化ステガノグラフィ
目的メッセージの内容を読めなくするメッセージの存在を隠す
検出可能性暗号文の存在は明らかメッセージの存在自体が不明
文字数への影響元のテキストと同程度カバーテキストの文字数が増加する場合がある
鍵の必要性復号に鍵が必要手法の知識があれば抽出可能な場合も
組み合わせ単独で使用可能暗号化と組み合わせると最強

最も安全なアプローチは、メッセージを暗号化した上でステガノグラフィで隠すことです。仮にステガノグラフィが破られてメッセージの存在が発覚しても、暗号化されていれば内容は読めません。

文字数カウントによるステガノグラフィの検出

テキストベースのステガノグラフィを検出する最もシンプルな方法は、文字数カウントです。以下のような不自然な差異が検出のヒントになります。

見た目の文字数と実際の文字数 (コードポイント数) の不一致。ゼロ幅文字が埋め込まれている場合、テキストエディタで見える文字数よりも、プログラムで数えた文字数の方が多くなります。例えば、見た目は 100 文字のテキストが、実際には 180 文字分のデータを持っている場合、80 個のゼロ幅文字が埋め込まれている可能性があります。

文字のエンコーディングサイズの不自然さも手がかりになります。純粋な ASCII テキスト (英数字のみ) であれば、UTF-8 で 1 文字 = 1 バイトです。しかし、キリル文字のホモグリフが混入していると、見た目は ASCII なのに一部の文字が 2 バイトになります。テキスト全体のバイト数が文字数より大きい場合、ホモグリフの存在を疑うべきです。

Twitter のゼロ幅文字対策と文字数カウント

Twitter (現 X) は、ゼロ幅文字を利用したステガノグラフィや文字数制限の回避を防ぐため、独自の文字数カウントルールを採用しています。Twitter の文字数カウントライブラリ「twitter-text」は、ゼロ幅文字を含む特定の Unicode 文字を文字数としてカウントします。つまり、ゼロ幅文字を大量に埋め込むと、見た目は短いテキストでも 280 文字の制限に達してしまうのです。

この対策は、ステガノグラフィの防止だけでなく、サービスの公平な利用を確保する目的もあります。ゼロ幅文字を無制限に埋め込めると、データベースのストレージを不当に消費したり、タイムラインの表示に問題を引き起こしたりする可能性があるためです。

ステガノグラフィの検出ツールと手法

テキストベースのステガノグラフィを検出するための専門ツールやテクニックがいくつか存在します。

検出手法対象原理限界
文字数 vs バイト数の比較ゼロ幅文字見た目の文字数と実際のバイト数の不一致正当なゼロ幅文字との区別が困難
Unicode カテゴリ分析ホモグリフテキスト中の文字が属する Unicode ブロックの一貫性を検証多言語テキストでは誤検出が多い
統計的分析空白操作スペースの分布が自然言語の統計と一致するか検証短いテキストでは精度が低い
エントロピー分析全般テキストの情報エントロピーが自然言語の範囲内か検証高度な手法には対応困難

最もシンプルで効果的な検出方法は、テキストを一度プレーンテキストにコピー&ペーストし、元のテキストとバイト数を比較することです。ゼロ幅文字やホモグリフが含まれていれば、バイト数に差異が生じます。文字数カウントツールで「見た目の文字数」と「Unicode コードポイント数」の両方を表示する機能があれば、この差異を即座に検出できます。

SNS とステガノグラフィ - 実際の事例

2016 年、セキュリティ研究者が Twitter (現 X) でゼロ幅文字ステガノグラフィが実際に使用されている事例を報告しました。ツイートの見た目は通常の 280 文字以内のテキストですが、ゼロ幅文字を含めると実際のデータ量ははるかに大きくなっていました。

一部の企業は、社内文書にゼロ幅文字で従業員 ID を埋め込む「文書フィンガープリンティング」を実施しています。機密文書が外部に流出した場合、埋め込まれたゼロ幅文字を解析することで、誰がリークしたかを特定できるのです。この手法は、文書の見た目を一切変えずに追跡情報を埋め込めるため、従来の透かし (ウォーターマーク) よりも検出が困難です。

ステガノグラフィは、プライバシー保護と情報セキュリティの両面で重要な技術です。検閲が厳しい国では、活動家がステガノグラフィを使って情報を発信しています。一方で、テロリストや犯罪者が通信を隠すためにも使われる可能性があります。文字数カウントという一見単純なツールが、こうした隠されたメッセージを検出する最初の防衛線になり得るのです。

情報セキュリティや暗号技術の関連書籍は Amazon でも探せます

この記事を共有