🐤

PDFから「存在を消す」Forensic Deep Purgeと、肉眼で見えない透かしStealth Watermarkの実装開発日誌 #6

に公開

開発日誌 #6 です。前回はMagic Pipelineの設計について書きました。

※検証環境は8年前のMacBook Airです。

今回は「見えないセキュリティ」を2つ紹介します。

  • Forensic Deep Purge:PDFからメタデータや隠しデータを物理的に抹消する
  • Stealth Watermark:肉眼では見えないが、流出経路を特定できる透かしを埋め込む

Forensic Deep Purge:「削除」では足りない

PDFを「名前を付けて保存」しても、元のファイルの痕跡が残ることがあります。

具体的には:

  • 作成者名・ソフトウェア名・作成日時などのメタデータ
  • 削除されたはずのテキストや画像(PDFの構造上、「隠れているだけ」のことがある)
  • XMPメタデータ(Adobeが策定した拡張メタデータ規格)
  • 非表示レイヤー・注釈の残骸

これらを「削除」するのではなく、必要な要素だけで新しいPDFを再構築することで物理的に排除します。
これが Zero-Trust Reconstruction の考え方です。

pub fn deep_purge(input: &[u8]) -> Result, PurgeError> {
    let mut doc = Document::load_mem(input)?;

    // 1. メタデータを完全削除
    doc.trailer.remove(b"Info");

    // 2. XMPメタデータストリームを削除
    if let Ok(catalog) = doc.catalog_mut() {
        catalog.remove(b"Metadata");
    }

    // 3. 全オブジェクトを走査して不要な情報を除去
    for (_, object) in doc.objects.iter_mut() {
        if let Ok(dict) = object.as_dict_mut() {
            for key in &[b"Author", b"Creator", b"Producer", b"CreationDate", b"ModDate"] {
                dict.remove(*key);
            }
        }
    }

    // 4. PDFを完全に再シリアライズ(構造ごと再構築)
    let mut output = Vec::new();
    doc.save_to(&mut output)?;
    Ok(output)
}

単純にメタデータを書き換えるだけでなく、再シリアライズによって構造ごとクリーンにするのがポイントです。


Stealth Watermark:見えないけど追跡できる

Layer 1: マイクロスタンプ(テキストレイヤー)

透明度を極限まで下げたテキストを各ページに埋め込みます。

pub fn embed_stealth_text(
    doc: &mut Document,
    page_id: ObjectId,
    stamp_text: &str,
) -> Result<(), lopdf::Error> {
    let content_stream = format!(
        "q\nBT\n/F1 1 Tf\n0.01 g\n100 100 Td\n({}) Tj\nET\nQ\n",
        stamp_text  // 例: "COPY-2024-USER-0042"
    );
    append_content_to_page(doc, page_id, content_stream.as_bytes())?;
    Ok(())
}

Layer 2: Forensic Ghost-Mark(メタデータ深部への電子署名)

pub fn embed_ghost_mark(
    doc: &mut Document,
    seal: &str,
) -> Result<(), lopdf::Error> {
    let catalog = doc.catalog_mut()?;
    catalog.set(b"HiyokoSeal", Object::string_literal(seal));
    Ok(())
}

通常のPDFビューアでは表示されませんが、lopdfで構造を見れば検出できます。


現在の状況(dev版)


次回

次回は Ollamaを使ったオフラインAIチャット の実装について書きます。


Hiyoko PDF Vault(日本語) → https://hiyokoko.gumroad.com/l/HiyokoPDFVault_jp
X → @hiyoyok

Discussion