トラブルシューティング: 署名とタイムスタンプの失敗
これらのエントリでは、エンジンが NextPDF\Exception\SignatureException と NextPDF\Security\Signature\Exception\SignatureLevelUnreachableException を通じて送出する署名の失敗を扱います。各エントリには正確なファクトリメソッドまたはクラスを示しているため、原因を推測せず、メッセージと getContext() から確認できます。
表現に関する注記: エンジンは、署名が有効であることや、ドキュメントが保護されていることを証明するものではありません。検出した失敗を報告します。各解決策は、報告された原因を取り除くための手順として扱ってください。
エントリ: PAdES レベル「B-LT」または「B-LTA」を生成できない
「エントリ: PAdES レベル「B-LT」または「B-LTA」を生成できない」という見出しのセクション- 症状。
SignatureException(メッセージ末尾はnextpdf/enterprise package is required for B-LT/B-LTA signatures)。 - 考えられる原因。 長期検証(LTV)機能のプロバイダーが存在しません。B-LT と B-LTA は失効情報とアーカイブタイムスタンプを埋め込みます。そのプロバイダーは
nextpdf/enterpriseに同梱されています。 - 証拠 / 診断。 ファクトリ
SignatureException::ltvCapabilityMissing()がこの正確なメッセージを生成します。getContext()は、試行したレベルに設定されたsignature_levelを返します。 - 解決策。
- プロバイダーをインストールします。
composer require nextpdf/enterpriseを実行します。 - 署名呼び出しを再実行します。
- プロバイダーをインストールできない場合は、代わりにコアパッケージが生成する
B-BまたはB-Tを要求してください。
- プロバイダーをインストールします。
- 関連項目。 例外リファレンス。
エントリ: 署名レベルが到達不能で、呼び出しが拒否される
「エントリ: 署名レベルが到達不能で、呼び出しが拒否される」という見出しのセクション- 症状。
SignatureLevelUnreachableException(メッセージはPAdES level "<x>" is unreachable (highest achievable: "<y>")という形式)。 - 考えられる原因。 要求された準拠レベルには、署名時に利用できないインフラストラクチャが必要です。多くの場合、B-T 以上ではタイムスタンプ局が該当します。エンジンはフェイルクローズで動作します。暗黙にダウングレードして、より高いレベルであると公示することはありません。
- 証拠 / 診断。
getContext()はrequestedLevel、highestAchievableLevel、reasonを返します。reasonフィールドには、インフラストラクチャの不足が記載されます。これは、満たしていないレベルを主張するドキュメントを防ぐために導入された、フェイルクローズのデフォルト動作です。 - 解決策。
- 不足しているインフラストラクチャを特定するために
reasonフィールドを読み取ります。 - 不足しているコンポーネントを用意し (たとえばタイムスタンプ局を構成し)、呼び出しを再実行します。
- 意図的に低いレベルを受け入れるには、
allowDegradation: trueをPadesOrchestratorに渡します。その場合、呼び出しはhighestAchievableLevelを生成し、生成したレベルを報告します。
- 不足しているインフラストラクチャを特定するために
- 関連項目。 暗号化と権限。
エントリ: タイムスタンプ局クライアントが必要だが存在しない
「エントリ: タイムスタンプ局クライアントが必要だが存在しない」という見出しのセクション- 症状。
SignatureException(末尾はTSA client is required for level <x> but none was provided)。 - 考えられる原因。 B-T、B-LT、または B-LTA の要求にはタイムスタンプ局クライアントが必要ですが、オーケストレーターに何も接続されていません。
- 証拠 / 診断。 ファクトリ
SignatureException::tsaRequired()がこのメッセージを生成します。getContext()は試行されたsignature_levelを保持します。 - 解決策。
- タイムスタンプ局クライアントを構成し、オーケストレーターに渡します。
- 呼び出しを再実行します。
- タイムスタンプを必要としないレベルを生成するには、
B-Bを要求します。
- 関連項目。 例外リファレンス。
エントリ: タイムスタンプ局のエンドポイント URL が空
「エントリ: タイムスタンプ局のエンドポイント URL が空」という見出しのセクション- 症状。
SignatureException(末尾はTSA endpoint URL is empty)。 - 考えられる原因。 タイムスタンプ局クライアントが、空のエンドポイント URL で構築されました。
- 証拠 / 診断。 ファクトリ
SignatureException::tsaUrlEmpty()がこのメッセージを生成します。これは構成上の不具合であり、ネットワーク障害ではありません。 - 解決策。
- タイムスタンプ局クライアントに、空でないエンドポイント URL を設定します。たとえば
https://timestamp.example.com/tsaです。 - 要求されたレベルでタイムスタンプが不要な場合は、代わりにタイムスタンプ局クライアントの接続を削除します。
- 呼び出しを再実行します。
- タイムスタンプ局クライアントに、空でないエンドポイント URL を設定します。たとえば
- 関連項目。 例外リファレンス。
エントリ: バッファに署名プレースホルダーがない
「エントリ: バッファに署名プレースホルダーがない」という見出しのセクション- 症状。
SignatureException(末尾はno /Contents <…> field found in PDF buffer (signature placeholder missing))。 - 考えられる原因。 署名ステージが、予約された署名コンテナを持たないバッファに対して実行されたため、署名を書き込む場所がありません。
- 証拠 / 診断。 ファクトリ
SignatureException::signatureContentsNotFound()がこのメッセージを生成します。 - 解決策。
- 署名ステージが実行される前に、署名フィールドとそのプレースホルダーが書き込まれていることを確認します。
- 署名の開始時にプレースホルダーが存在するように、パイプラインを再実行します。
- 関連項目。 例外リファレンス。
エントリ: 失効ステータスが不明 (OCSP レスポンダーが拒否)
「エントリ: 失効ステータスが不明 (OCSP レスポンダーが拒否)」という見出しのセクション- 症状。
SignatureException(末尾はOCSP responder returned non-successful OCSPResponseStatus "<status>")。 - 考えられる原因。 OCSP レスポンダーが
successfulステータスを返さなかったため、失効に関するアサーションを生成しませんでした。エンジンは、ソース内で引用している RFC 6960 §4.2.1 に従います。これによれば、内容のあるレスポンスボディはsuccessful (0)ステータスに対してのみ許可されます。エンジンは、拒否されたレスポンスを信頼できる肯定的な結果として扱うことを拒否します。 - 証拠 / 診断。 ファクトリ
SignatureException::nonSuccessfulOcspResponseStatus()がこのメッセージを生成し、報告されたステータス(たとえばtryLaterやinternalError)を示します。予約済みまたは不明なステータスバイトの場合は、代わりにSignatureException::reservedOcspResponseStatus()が生成されます。 - 解決策。
- メッセージ内のステータスを特定します。
tryLaterのような一時的なステータスの場合は、後で失効情報の取得を再試行します。 - ステータスが
unauthorizedまたはmalformedRequestの場合は、OCSP リクエスト URL と、レスポンダーが期待する証明書を確認します。 - B-LT または B-LTA のアーティファクトを取得できなかった失敗を握りつぶさないでください。失効に関するアサーションは、そのレベルの一部です。
- メッセージ内のステータスを特定します。
- 関連項目。 例外リファレンス。
エントリ: 証明書チェーンのエントリのデコードに失敗する
「エントリ: 証明書チェーンのエントリのデコードに失敗する」という見出しのセクション- 症状。
SignatureException(末尾はfailed to base64-decode PEM body — input is not valid PEM)。 - 考えられる原因。 証明書チェーンのエントリが有効な PEM ではありません。通常は切り詰め、紛れ込んだ文字、または PEM が期待される箇所に渡されたバイナリ DER ブロブが原因です。
- 証拠 / 診断。 ファクトリ
SignatureException::pemDecodingFailed()が、チェーンの組み立て中にこのメッセージを生成します。 - 解決策。
- チェーン内の各証明書に、紛れ込んだ文字や切り詰めがないか確認します。
- 該当する証明書を PEM 形式で再エクスポートします。
- 署名呼び出しを再実行します。
- 関連項目。 暗号化と権限。
エントリ: 秘密鍵の種類がアルゴリズムと一致しない
「エントリ: 秘密鍵の種類がアルゴリズムと一致しない」という見出しのセクション- 症状。
SignatureException(末尾はexpected private key of type "<x>" for the configured algorithm but got "<y>")。 - 考えられる原因。 読み込まれた秘密鍵が、構成された署名アルゴリズムと一致しません。たとえば、ECDSA を選択しているのに RSA 鍵を使用している場合です。
- 証拠 / 診断。 ファクトリ
SignatureException::unexpectedKeyType()がこのメッセージを生成し、期待される鍵クラスと実際の鍵クラスの両方を示します。 - 解決策。
- 証明書と鍵ペアが、選択したアルゴリズムと一致していることを確認します。
- アルゴリズムの選択を鍵に合わせて変更するか、アルゴリズムに合致する鍵を読み込みます。
- 署名呼び出しを再実行します。
- 関連項目。 例外リファレンス。
エントリ: Ed25519 の鍵または署名マテリアルが不正
「エントリ: Ed25519 の鍵または署名マテリアルが不正」という見出しのセクション- 症状。 Ed25519 の長さの不一致を示す末尾を伴う
SignatureException。たとえばEd25519 signature length <n> ≠ expected 64 bytesやEd25519 round-trip self-verify failedです。 - 考えられる原因。 ランタイムの暗号ビルドが誤った長さの鍵または署名マテリアルを返したか、生成したばかりの署名がそれ自身の公開鍵に対して検証できませんでした。エンジンはソース内で RFC 8032 §3.4 を引用しており、これは分離された Ed25519 署名を 64 バイトに固定します。エンジンは、自己検証できないマテリアルを送出するのではなく、処理を中止します。
- 証拠 / 診断。 関連するファクトリは
SignatureException::ed25519SignatureMalformed()、::ed25519RoundTripVerifyFailed()、::ed25519KeyParseFailed()、::ed25519SeedInvalid()、::ed25519SecretKeyMalformed()、および::ed25519PublicKeyInvalid()です。いずれも、観測された長さを示します。 - 解決策。
- libsodium PHP 拡張を再インストールします。除去された、または破損したビルドが、誤った長さのマテリアルの記録された原因です。
- 鍵が Ed25519 鍵であること、および OpenSSL が 1.1.1 以降であることを確認します。
- 署名呼び出しを再実行します。
- 関連項目。 例外リファレンス。
エントリ: アーカイブタイムスタンプ辞書が出力されなかった
「エントリ: アーカイブタイムスタンプ辞書が出力されなかった」という見出しのセクション- 症状。
SignatureException(末尾はno /Type /DocTimeStamp dictionary was emitted into the PDF buffer)。 - 考えられる原因。 B-LTA のアーカイブループは実行されたものの、ドキュメントタイムスタンプ辞書がバッファに到達しなかったため、アーティファクトは書き込みが不完全な B-LTA になってしまいます。エンジンは、これを返すことを拒否します。
- 証拠 / 診断。 ファクトリ
SignatureException::documentTimestampNotEmitted()がこのメッセージを生成します。これは、ファイナライズ時に送出される事後条件の失敗です。 - 解決策。
- 出力は破棄されたものとして扱い、不完全なアーティファクトを出荷しないでください。
- 到達可能なタイムスタンプ局を用意して、B-LTA パイプラインを再実行します。
- 失敗が繰り返される場合は、不具合報告のために
getContext()と、連鎖した直前の例外を取得します。
- 関連項目。 例外リファレンス。
エッジケースと注意点
「エッジケースと注意点」という見出しのセクション- これらのファクトリは、サブジェクトまたはサムプリントが利用可能な場合にのみ
cert_infoを設定します。機能上および構成上の失敗では、空のcert_infoが想定されます。 - HTTP クライアントを構成していない B-LT または B-LTA の要求は、
SignatureException::httpClientMissing()を送出します。失効情報の取得には、オーケストレーターに渡された PSR-18 クライアントが必要です。 - 署名者の実装がない HSM ベースの証明書は、
SignatureException::hsmSignerMissing()を送出します。署名する前に、署名者を証明書に接続してください。
用語集: PAdES レベル · 失効に関するアサーション