セキュリティ
C2PAで時間をハックする方法
How to hack time, with C2PA (da.vidbuchanan.co.uk)
要約
C2PAメタデータの「除外」機能の脆弱性を利用して、画像が作成されたとされるタイムスタンプよりも後に編集されたにも関わらず、有効なタイムスタンプ付き署名を維持する方法を解説しています。この手法は、画像編集の信頼性を損なう可能性があり、C2PA仕様の改善が必要であることを示唆しています。
全文翻訳
C2PAで時間をハックする方法
デビッド・ブキャナン(別名retr0id)著、2026年10月2日
映画史上最も印象的なハッキングのスタントは、Kung Fury (2015) のHackermanが時間をハックするシーンです。彼はこの力を使って歴史的な過ちを正します。しかし、もし私に時間をハックする能力があったら、何をしますか?個人的にはバタフライエフェクトがより怖いので、宝くじの当選番号を自分に教えるために数時間戻るだけでしょう。実際、暗号学的に改ざん不可能なこの画像のC2PAメタデータによれば、まさにそれを行ったのです。
はい、フォトショップで加工したことがわかります。ここでは実際の宝くじ詐欺をしようとしているわけではありません。C2PAメタデータ(タイムスタンプを含む)は、https://verify.contentauthenticity.org/ で検証できます(もしあなたが未来でこれを読んでいるなら、彼らが緩和策を導入しているかもしれません)。宝くじの当選番号が、抽選時間の数時間前に表示されていることを、https://www.euro-millions.com/results/28-08-2026 で確認できます。
背景
典型的なC2PAマニフェストには2つの署名が含まれています。最初の署名は「クレーム」署名です。カメラアプリの場合、クレームは「これはGPS座標、この時間で撮影された写真です」といったものかもしれません(C2PA仕様に従って、より正式に表現されます)。私の以前の記事で、クレーム署名はほぼ無価値であり、好きなクレームに署名できることを示しました(少なくとも、Google PixelカメラアプリのようなフラッグシップC2PA実装では可能です)。しかし、通常はタイムスタンプオーソリティ(TSA)からの2番目の署名があり、こちらの方が興味深いです。デバイスが自身の時間を伝えることを信頼しないため、代わりにRFC 3161プロトコルを介してリモートサーバーに問い合わせます。サーバーは「はい、このハッシュをこのタイムスタンプで見ました」と主張する署名を返します。この応答はC2PAメタデータに埋め込まれます。サーバーが不正に動作していないと信頼する限り、これは指定されたタイムスタンプ以降に署名されたデータが存在したことを証明します。TSAは独立した証人のように機能します。
Pixel 10では、Googleはデバイスが自身の時間を伝えることを信頼できると決定しました。私はまだ彼らの「オンデバイス信頼タイムスタンプ」実装を評価していませんが、非常に懐疑的です。それにもかかわらず、この記事ではTSAを攻撃しません。TSAは宣伝通りに機能すると仮定します。
時間をハックする時間
TSAメカニズムが安全である場合、どのように時間をハックするのでしょうか?私たちは私のお気に入りのバグクラス、つまり仕様のフットガンを使用します。フットガンは次のとおりです。
C2PAは任意の「除外」を許可します。これらは、ファイル内の署名計算から除外されるバイト範囲です。はい、本当に。これはすでに知られています(文字通り仕様に記載されています)が、なぜか誰もまだ何もしていません。実際、Neal Krawertz博士は2025年6月に公開されたC2PAの欠点の「大きな箇条書きリスト」でこれを明確に指摘しました。
大きな除外範囲。マニフェストは通常、署名から非常に大きなバイト範囲を除外します。除外されたバイトは検出なしに変更できます。唯一の新しい点は、悪意のある署名者が意図せずではなく、意図的に大きな除外範囲を使用できることです。ファイル全体を除外して、空の文字列に対する完全に有効な署名を生成できます。これにより、署名を無効にすることなく、TSAのタイムスタンプ証明を無効にすることなく、後からファイルを改ざんできます。
時間ステータス:ハック済み
私は実際に宝くじ券の写真を撮り、有効なC2PA署名と有効な信頼されたタイムスタンプを添付しました。しかし、私はマニフェストをファイル全体を除外するように作成したので、番号が発表された後に(下手ですが)フォトショップで加工しても、署名のいずれも無効になりませんでした。
私のPoCファイルのC2patool -dを使用してマニフェストをダンプすると、重要な部分が見えます。
1 2 3 4 5 6 7 8 9 10 11 12
"c2pa.hash.data": {
"exclusions": [
{
"start": 0,
"length": 3995383
}
],
"name": "jumbf manifest",
"alg": "sha256",
"hash": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
"pad": []
},
3995383はファイル全体の長さであり、47DE...uFU=は空文字列のハッシュです。
$ openssl sha256 -binary /dev/null | base64
47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
クレーム署名はそのハッシュに対して行われ、タイムスタンプ署名はクレーム署名に対して行われます。実質的に何も署名していませんが、今日現在、私が発見した全てのC2PA検証ツールは何も異常としてフラグを立てていません。
修正できますか?
簡単ではありません!確かに、ファイル全体が除外されていることを検出して無効として報告するのは簡単ですが、一部だけが除外されている場合はどうでしょうか?それが無害なものなのか、それとも修正された場合に画像の見た目を完全に変える可能性のあるものなのかをどのように判断しますか?(後者の例としてMD5ハッシュ衝突PoCを参照してください)。
この投稿の最初のドラフトは「私の推奨は、除外機能はC2PA仕様から除外されるべきだ」で終わっていましたが、それほど単純ではありません!除外が存在する主な理由は、特定のファイル形式がそれを効果的に必要とするからです。例えばPNGファイルでは、各チャンクにはCRC32チェックサムがあり、署名がファイルに埋め込まれた後に修正する必要があります。これは循環依存関係を生み出すため、CRC32が署名の範囲から除外されない限り(CRCを無効にしない巧妙な数学的トリックを無視すれば)です。
それを念頭に置くと、ここで正しい解決策は、サポートされている各ファイル形式について、ファイルのどの部分が除外を許可されるかを慎重かつ明示的に指定し、検証者がこれらの制約を強制することを要求することだと思います。