コンテンツにスキップ
getnextpdf.com

署名済み合意書のワークフロー

Spec: ETSI EN 319 142-2, §5.1Spec: ISO 32000-2:2020, §12.8

署名済み合意書とは、「署名が付いただけの PDF」ではありません。それは、署名が正しいバイト列を保護するように準備された文書です。義務に見合ったレベルで署名され、署名証明書の有効期限が切れた後も検証できるようにパッケージ化されます。このページでは、そのシナリオを白紙の文書から長寿命の契約書まで順を追って解説します。そして、どの段階を今日のエンジンが配線しているのか、どの段階を凍結されたサーフェスとして公開しているのかを率直に示します。

署名した当日は検証できるのに、3 年後の紛争の場面で検証に失敗する契約書は、署名がまったくないよりも悪いものです。誰かがそれを頼りにしてしまったからです。失敗の原因が暗号技術そのものであることはまれです。たいていは、署名者がとうにその場を離れた後になって判明する、欠落したタイムスタンプや欠落した失効証拠です。

署名の義務を最初に選び、その義務が必要とする証拠を署名の時点で生成すること — これが、持ちこたえる合意書と、静かに劣化していく合意書との分かれ目です。これは、紛争のたびに改めて気づくのではなく、ワークフローの中で一度だけ下すべき判断です。

  • 準備してから署名する。 署名は、計算対象となったバイト範囲を正確にカバーします。後から追記されるリビジョンも含めて、署名の後ではなく前に、文書を最終版として確定してください。
  • レベルは義務に合わせて選び、その逆をしない。 PAdES は段階的な進行を定義しています。基本的な署名、タイムスタンプ付きの署名、検証用素材を埋め込んだ署名、そして無期限のアーカイブ有効性のために再タイムスタンプされた署名です(ETSI EN 319 142-2 §5.1)。
  • 長期有効性はプロパティではなく構造です。 それは、ファイルの中に書き込まれた Document Security Store とドキュメントタイムスタンプです(ISO 32000-2:2020 §12.8)。
  • シーム(接合部)について正確であること。 NextPDF の高レベルな Document::setSignature() は公開 API を凍結しますが、未署名のファイルを出力するのではなく、即座に失敗します。配線されている経路は、より低レベルのオーケストレーターです。このページはそうでないふりをしません。

NextPDF は判断仕組みを分離します。判断とは、義務がどの PAdES レベルを必要とするかということです。仕組みとは、バイト列がどのように署名され、検証用素材がどのように運ばれるかということです。この 2 つを一体のものとして扱うことが、有効ではあるが永続しない署名にチームが行き着く原因です。

このシナリオには 4 つの段階があります。

  1. 文書を準備する合意書を作成し、確定版として扱います。署名はこの正確なバイト範囲を保護し、新しいリビジョンなしにその外側へ追加されたものは保護しません。
  2. 義務を選択するB-B は署名者を証明します。B-T は信頼できる時刻を追加します。B-LT は後で検証するための材料を埋め込みます。B-LTA は無期限の有効性のために再スタンプします。
  3. 署名するCMS 署名がバイト範囲にわたって署名ディクショナリに埋め込まれ、レベルが必要とする場合は TSA からタイムスタンプが要求されます。
  4. 保全する長期レベルでは、署名が証明書よりも長く存続するように、Document Security Store と文書タイムスタンプが書き込まれます。
署名済み合意書のシナリオを端から端まで示します。各段階が 1 つの保証を追加し、第 2 段階で選ぶレベルが、第 3 段階と第 4 段階でどれだけの証拠を生成しなければならないかを決めます。

このレベルの enum は実在し、義務を正直に符号化しています。B-B は署名者の身元を証明します。B-T は信頼できるタイムスタンプを追加します。「いつ」は「誰が」と同じくらい厳密に問われます。B-LT は、署名証明書の有効期限が切れた後に署名を検証するために必要な証明書と失効応答を埋め込みます。B-LTA はドキュメントタイムスタンプを追加し、各タイムスタンプ証明書が失効する前に再タイムスタンプすることで、信頼の連鎖を無期限に延長できるようにします。この enum は、どのレベルがタイムスタンプを必要とし、どのレベルが埋め込みの検証用素材を必要とするかを把握しているため、エンジンは、誤解を招くような「署名済み」のファイルを生成する代わりに、不可能な組み合わせを拒否できます。

ここでは、実際の enum を使って判断 — 義務の選択 — を示します。配線されている署名経路は、より低レベルのオーケストレーターです。高レベルの呼び出しは、フェイルファストの挙動を明示するためだけに示しています。

<?php
declare(strict_types=1);
use NextPDF\Security\Signature\SignatureLevel;
/**
* Map a business obligation to a PAdES level.
*
* The obligation drives the level, not the reverse — choosing B-B for a
* 10-year contract is a decision you do not want to make implicitly.
*/
function levelForObligation(string $obligation): SignatureLevel
{
return match ($obligation) {
// Internal sign-off, short retention, signer identity is enough.
'internal_approval' => SignatureLevel::PAdES_B_B,
// Counterparty agreement: prove the moment of signing.
'counterparty_agreement' => SignatureLevel::PAdES_B_T,
// Regulated contract that must verify after cert expiry.
'regulated_contract' => SignatureLevel::PAdES_B_LT,
// Long-lived legal record: indefinite, re-stampable validity.
'long_term_legal_record' => SignatureLevel::PAdES_B_LTA,
default => throw new \InvalidArgumentException(
"Unknown obligation: {$obligation}",
),
};
}
$level = levelForObligation('regulated_contract');
// The enum carries the obligation's implications with it.
$needsTsa = $level->requiresTimestamp(); // true for B-T+
$needsDss = $level->requiresDss(); // true for B-LT+
$needsArchive = $level->requiresDocumentTimestamp(); // true only for B-LTA

レベルオブジェクトはラベルではありません。義務が何を伴うかに答えてくれるため、下流の配線がそれを改めて導き出す必要はありません。

繰り返し現れる誤解は、*「署名は有効だから、これで完了だ」*というものです。今日有効であることは必要条件ではありますが、十分条件ではありません。署名はバイト範囲に対して計算されます。後のリビジョンでその範囲の外に追記されたものは署名の対象外であり、これこそが、準備が署名の前に来る理由です。そして、今検証できる署名でも、署名時に検証用素材が埋め込まれていなければ、証明書の有効期限が切れたときに後で失敗しうるのです。「有効」と「永続的」は別々の保証であり、実際にどちらが必要かを教えてくれるのは義務だけです。

これに関連した、このエンジン固有の落とし穴があります。高レベルの setSignature() が今日署名済みファイルを生成すると思い込むことです。そうはなりません。意図的に即座に失敗します。その診断を契約(コントラクト)として扱ってください。

  • Document::setSignature() は配線された署名器ではなく、凍結された公開サーフェスです。 ブロッキングな診断とともに即座に失敗します。署名済みファイルの代わりに未署名の PDF を出力することは決してありません。配線されている経路は、より低レベルの 2 フェーズのオーケストレーターです。
  • 長期検証の保守(DSS/VRI、ヘルスチェック、アーカイブタイムスタンプループ)は Premium ティアの機能です。 Core はアーカイブループを提供しません。以下の境界を参照してください。
  • 署名は自身のバイト範囲を正確に保護します。 後から追記されたリビジョンは別個のものです。エンジンがカバレッジをさかのぼって拡張することはありません。
  • NextPDF は構造を生成し保守しますが、判定は行いません。 署名が信頼されるかどうかは、検証側のトラストアンカーとポリシーに依存し、それらはエンジンの外側にあります。
  • B-LTA だけで署名が永遠になるわけではありません。 各タイムスタンプ証明書の有効期限が切れる前に、再タイムスタンプのループがスケジュールどおりに実行される場合に限り、無期限の有効性が実現します。
  • このページは、Premium のアーカイブサーフェスについては挙動レベルの記述にとどまります。特定の裁判所や当局による受理を主張するものではありません。
PAdES 署名と長期的な有効性 — edition availability
EditionAvailability
Core

Core は SignatureLevel enum と、凍結された Document::setSignature() サーフェス(フェイルファスト)を公開します。配線された低レベルのオーケストレーターがベースライン署名をカバーします。長期アーカイブの保守は Core には含まれません。

Pro

オーケストレーターを介した PAdES ベースライン署名(B-B / B-T)が利用できます。

Enterprise

B-LT / B-LTA、Document Security Store と署名ごとの VRI 保守、LTV ヘルスチェック、そして無期限の有効性のためのドキュメントタイムスタンプのアーカイブループを追加します。

  • PAdES ベースラインプロファイルB-BB-TB-LTB-LTA を段階的な進行として説明し、どう選ぶかを解説します。
  • 長期検証 — 今日検証できる署名が 10 年後に失敗しうる理由と、LTV がどのように証拠を埋め込むか。
  • 統合の意思決定ガイド — どのエコシステムパッケージが署名ワークフローに適しているか、 NextPDF Connect における人による承認のシームも含めて解説します。
  • PAdES — PDF Advanced Electronic Signatures。高度電子署名が PDF の中でどのように運ばれるかを定義する ETSI のプロファイルファミリー。
  • バイト範囲(Byte range) — 署名が計算対象とする、連続したファイルバイトの範囲。その外側のコンテンツは、その署名では保護されません。
  • 署名レベル(B-B / B-T / B-LT / B-LTAPAdES の進行です。誰が、 いつ署名したか、埋め込みの検証用素材を伴うか、そして無期限のアーカイブ有効性のために再タイムスタンプ可能か、を表します。
  • TSA — Time-Stamping Authority(タイムスタンプ局)。ある文書の状態が特定の UTC 時刻に存在したことを主張する RFC 3161 のサービス。
  • DSS(Document Security Store) — 証明書の有効期限が切れた後に署名を検証するために必要な、証明書・OCSP 応答・CRL のファイル内ストア。
  • LTV(Long-Term Validation、長期検証) — 検証用の証拠を埋め込み、それを再タイムスタンプすることで、署名を時間の経過を通じて検証可能に保つこと。
  • フェイルファスト(Fail-fast) — ひそかに誤ったファイルを出力するのではなく、 誤解を招く成果物の生成を拒否し、代わりに対処可能なエラーを送出すること。