【Node】これから必須のC2PAを読み込んでみた
こんにちは、フリーランスエンジニアの太田雅昭です。
C2PA
C2PAは、画像や動画、音声、PDFに署名をし、改竄を防ぐ仕組みです。自動生成が今後伸びていくので、こうした出所を示す技術は必須となってきます。
証明書のリストについては、下記に書かれています。
https://opensource.contentauthenticity.org/docs/verify-known-cert-list
2025年3月28日現在、信頼された証明書のリストは仮のものです。ざっとみてみたところ、AdobeやMicrosoft, Tiktokなどが登録されていました。この仮のリストは本番に移行した際にdeprecatedになるため、その時にシステムの修正が必要になります。仮のリストに登録するには、実際に運用を始めてからメールで申請するようです。
簡単なテスト
C2PAの検証は下記サイトで行えます。
https://contentcredentials.org/verify
検証のための画像は、C2PA公式にあります。
https://c2pa.org/public-testfiles/image
C2PA Toolsのテスト用証明書で作成されています。Verify tool’s temporary known certificate list.に登録されていないため、This Content Credential was issued by an unknown source.というメッセージが表示されます。
Node.jsでのC2PA
Node.jsでは、下記のライブラリがあります。
https://github.com/contentauth/c2pa-node
2025年3月28日現在プレリリース版なので、とりあえず使ってみるには良いと思います。ただ本番ではバイナリを直接呼び出す方がいいかもしれません。
使ってみる
まずは公式からC2PAの埋め込まれたテスト画像ファイルをダウンロードします。
https://c2pa.org/public-testfiles/image
今回、assetsフォルダに入れました。
インストールします。
npm i c2pa-node
npm i -D @types/node
下記のコードを実行します。
import { createC2pa } from 'c2pa-node';
import { readFile } from 'node:fs/promises';
const c2pa = createC2pa();
async function read(path, mimeType) {
const buffer = await readFile(path);
const result = await c2pa.read({ buffer, mimeType });
if (result) {
const { active_manifest, manifests, validation_status } = result;
console.log(active_manifest);
} else {
console.log('No claim found');
}
}
read('assets/adobe-20220124-A.jpg', 'image/jpeg');
下記の結果となりました。
No claim found
これは、C2PA署名の入っていないファイルのためです。今度は、署名の入っているファイルで試します。
assets/adobe-20220124-C.jpgです。すると以下の結果が出ました。
{
claim_generator: 'make_test_images/0.16.1 c2pa-rs/0.16.1',
title: 'C.jpg',
format: 'image/jpeg',
instance_id: 'xmp:iid:f7ba134b-8dec-4334-911d-a30409e32d8e',
thumbnail: {
format: 'image/jpeg',
data: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 01 00 01 00 00 ff c0 00 11 08 02 ab 04 00 03 01 11 00 02 11 01 03 11 01 ff db 00 43 00 06 04 05 06 05 04 ... 31558 more bytes>
},
ingredients: [],
assertions: [
{
label: 'stds.schema-org.CreativeWork',
data: [Object],
kind: 'Json'
},
{ label: 'c2pa.actions', data: [Object] }
],
signature_info: {
alg: 'Ps256',
issuer: 'C2PA Test Signing Cert',
cert_serial_number: '720724073027128164015125666832722375746636448153',
time: '2023-01-24T14:48:56+00:00',
timeObject: 2023-01-24T14:48:56.000Z
},
label: 'contentauth:urn:uuid:4d971750-1db4-4492-a87c-5c3e7ed33efc'
}
active_manifestの結果のみです。
検証も行うには、validation_statusを見るようです。今回の画像では、リスト登録されていない証明書のためか、validation_statusは空配列でした。
各要素の解説
ChatGPTに、上記の結果について解説してもらいました。
基本情報
claim_generator
:
→ 画像にC2PAメタデータを埋め込んだツールとバージョン。
→make_test_images/0.16.1
とc2pa-rs/0.16.1
を使用している。title
:
→ 画像のファイル名 (C.jpg
)。format
:
→ 画像のフォーマット (image/jpeg
)。instance_id
:
→ 画像の一意の識別子(XMPのxmp:iid
に基づく)。
サムネイル
thumbnail
:
→ 画像のサムネイル(プレビュー用の小さい画像)がJPEGフォーマットで格納されている。
成分情報
ingredients
:
→ 画像の元となる要素(別の画像やコンテンツ)がある場合、それらがここに記録される。
→ 今回は空 ([]
) なので、元データの情報は記録されていない。
アサーション
assertions
:
→ 画像に関連するメタデータを保持するリスト。stds.schema-org.CreativeWork
:
→schema.org
のCreativeWork
に関するメタデータ(詳細はdata
の中)。
→ 例えば、著作権情報や作成者情報などが含まれる可能性がある。c2pa.actions
:
→ 画像に行われた処理やアクション(例えば、編集やフィルター適用の履歴)。
署名情報
signature_info
:
→ このC2PAデータが改ざんされていないことを保証するためのデジタル署名情報。alg
:
→ 署名アルゴリズム (Ps256
= RSA PSS with SHA-256)。issuer
:
→ 署名を発行した証明機関(この場合C2PA Test Signing Cert
)。cert_serial_number
:
→ 証明書のシリアル番号。time
/timeObject
:
→ 署名が行われた時刻 (2023-01-24T14:48:56Z
)。
ラベル
label
:
→ コンテンツ認証のURN(UUID形式)。
→contentauth:urn:uuid:4d971750-1db4-4492-a87c-5c3e7ed33efc