電子署名検証の設計。チェーン・失効・3つの時刻

電子署名検証の設計。チェーン・失効・3つの時刻

「電子署名を検証しました」という一文は、実装を見ないと何も意味しません。カードから署名値を読み出しただけでも、暗号ライブラリのverifyがtrueを返しただけでも、開発現場ではしばしば「検証できた」と表現されるからです。しかし犯収法のJPKI方式や電子契約の証拠力という文脈で通用するのは、そのうちのごく一部の状態だけです。本記事は、実装者が検証手順を組み立てられるだけでなく、発注者・事業会社の開発責任者が「うちのシステムは実際どこまで確認しているのか」をベンダーに問い返せるよう、検証の順序・失効確認の運用・時刻の記録設計を整理します。確認日: 2026年8月23日。

この記事の要点

  • 署名検証は単一の処理ではなく「チェーン構築→署名値→有効期間→失効確認」の連鎖です。1つ省くたびに、それに対応する攻撃・事故が素通りします
  • トラストアンカー(信頼の起点)をどう管理するかは自社の責任であり、チェーン全段が失効確認の対象です。署名者証明書だけ見て中間CAを見ない実装は片手落ちです
  • CRL/OCSPは外部依存なので必ず落ちます。落ちたときに通すか(fail-open)止めるか(fail-closed)は技術ではなく業務リスクの判断で、平時に決めて文書化しておく必要があります
  • 署名時刻・検証時刻・失効時刻の3つを混同した記録は、後日の監査で説明できません。原則として問われるのは「署名時点で有効だったか」です

「検証できた」には3つの強さがある

議論の前に、言葉の解像度を上げます。マイナンバーカードの署名を「検証した」という表現には、少なくとも次の3段階が混在しています。

  1. カードから証明書と署名値を読み取れた — 読めただけで、正しさは何も確認していない状態です
  2. 署名値を証明書の公開鍵で暗号学的に検証できた — そのデータがその秘密鍵で署名されたという事実の確認までです
  3. 証明書チェーン・有効期間・失効状態まで確認できた — 信頼できる発行者が出した、有効な証明書による署名だと言い切れる状態です

業務上の意味を持つのは3だけです。1と2は、極端に言えば自分で作った自己署名証明書でも成立してしまいます。「攻撃者が自分で鍵ペアを作り、自分で署名し、自分の証明書を添えて送る」という単純な手口が、2で止めた実装では通ってしまうわけです。

実務上の落とし穴は、SDKやライブラリの「verify成功」がどの段階を指すかが製品ごとに違うことです。署名値の照合だけを行い、チェーンや失効の確認は呼び出し側の責任としているライブラリは珍しくありません。導入時には必ずドキュメントで確認し、足りない段階を自社側で埋める設計にしてください。発注者側のレビューでは、「verifyがtrueを返した」ではなく「どの段階まで確認しているのか」を1問目に置くのが有効です。

検証の順序。4ステップの連鎖として実装する

段階3を分解すると、次の順序になります。この順序自体に意味があります。チェーンが構築できていない状態で署名値だけ照合しても、その公開鍵が誰のものか分からないままだからです。

ステップ確認内容省くと通るもの
1チェーン構築署名者証明書から信頼の起点(トラストアンカー)までの発行者連鎖を構築し、各段の署名を検証する自己署名のなりすまし証明書
2署名値検証対象データのハッシュと署名値を、署名者の公開鍵で照合する文書の改ざん
3有効期間チェーン上の全証明書が、基準時刻において有効期間内かを確認する期限切れ証明書の使用
4失効確認チェーン上の証明書が失効していないかをCRL/OCSPで確認する失効済み(漏えい・住所変更等)証明書の使用

この表で押さえるべき設計上の要点は2つあります。

第一に、トラストアンカーの管理は自分の責任です。 何を信頼の起点として設定するかで、検証結果の意味そのものが決まります。トラストアンカーの取得経路が曖昧なら、その上でどれだけ厳密にチェーンを検証しても意味がありません。JPKIであれば公的なCA証明書を正規の経路で取得し、更新にも追随する運用が要ります。「アンカーは誰が、どの経路で入れ替えるのか」を運用手順として持っていない現場は、実は珍しくありません。

第二に、失効確認の対象はチェーン全段です。 署名者証明書だけ失効確認して中間CAを確認しない実装は、CAの鍵が危殆化したケースを取りこぼします。実装レビューでは、リーフだけでなく上位証明書についても失効情報を取りに行っているかを確認してください。

なおJPKIの場合、失効確認(J-LISへの照会)を民間事業者が自ら行うには公的個人認証法に基づく主務大臣の認定が必要で、実務では認定プラットフォーム事業者を経由する構成が一般的です。自社が認定を取るのか、PFのサービスを使う立場に立つのかという分岐はJPKIのPF方式とSP方式で詳しく整理しています。本記事の設計論は、自前検証でもPF経由でも「結局のところ何が確認されているのか」を発注者・開発者が読み解けるようになるための地図です。カードから証明書を読み出す物理層の挙動についてはマイナカードをNFCで読む裏側が参考になります。

失効確認の運用設計。CRL/OCSPは落ちる前提で組む

4ステップの中で、平常運転を最も脅かすのが失効確認です。他の3つは自分の計算機の中で完結しますが、失効確認だけは外部への問い合わせであり、可用性の問題を必ず持ち込むからです。

方式は大きく2つあります。

  • CRL(証明書失効リスト): 失効リストを定期的に取得し、手元で照合する方式です。取得間隔がそのまま失効情報の鮮度になります。キャッシュが効いて外部依存を減らせる一方、「前回取得から次の更新までの空白」を業務として許容する設計が要ります
  • OCSP: 証明書単位でオンライン照会する方式です。鮮度は高いものの、照会先の遅延や障害がそのまま自社の処理時間に乗ります。タイムアウト値・リトライ回数・その間ユーザーに何を見せるかの設計が必須です

そのうえで、最も重要な設計判断がこれです。失効確認ができなかったとき、どうするのか。

方針内容向く場面
fail-closed確認できなければ署名を受け付けない口座開設・高額契約など、なりすましによる損失が大きい処理
fail-open一時的に通し、後で確認して必要なら巻き戻す停止の業務影響が大きく、事後救済のフローが設計できる処理

どちらが正しいかは業務によって変わります。決済や口座開設のようになりすましの損失が非対称に大きい処理ならfail-closedが原則ですし、大量の日常取引を止めることの損失が上回るなら、後追い確認と巻き戻しを設計したうえでfail-openを選ぶ判断もありえます。

本当に危険なのは、どちらでもなく「決めていない」ことです。障害が起きた夜に現場の判断で通してしまい、その判断の記録も残らない——これが最悪のパターンです。方針・判断者・エスカレーション経路・記録方法を平時に文書化しておいてください。そしてどちらの方針を採る場合でも、「失効確認をいつ・どの情報源で行ったか、あるいは行えなかったか」を証跡として残します。この証跡の粒度と保存の考え方はeKYCの証跡設計にまとめています。

PF経由でJPKIを使う場合、この判断の一部はPFのSLAと障害時ポリシーに依存します。「PF側で失効確認が返らないとき、APIは何を返すのか。それを自社はどう解釈するのか」は、契約前に確認すべき項目です。

3つの時刻を混同しない

監査や紛争の場面で決定的に効いてくるのが、時刻の区別です。署名まわりには少なくとも3つの異なる時刻が登場します。

  • 署名時刻: 署名が行われた時点
  • 検証時刻: 自社が検証処理を実行した時点
  • 失効時刻: 証明書が失効した時点

原則として問うべきは「署名時刻において証明書が有効だったか」です。署名の後に証明書が失効しても——たとえば引っ越しによって署名用電子証明書が失効しても——署名した時点で有効だったのであれば、署名の効力の前提は保たれます。逆に、検証時刻の失効状態だけを記録している設計だと、「署名時点では有効だったのに、後日の再検証で失効と表示され、説明に窮する」という状況を招きます。

この区別を実装に落とし込むと、次の3点になります。

  • 検証結果の記録に3つの時刻をすべて残す。署名時刻、検証時刻、そして参照した失効情報の基準時刻(CRLのthisUpdate相当、OCSPレスポンスの生成時刻)です。特に3つ目は忘れられがちですが、「どの時点の鮮度の情報で判断したか」を示す唯一の材料です
  • 長期に効力を主張したい文書は、署名時刻の証明と検証材料の保全までセットにする。信頼できるタイムスタンプで署名時刻を固定し、検証に使った証明書・失効情報を文書とともに保全しておく設計です。この延長線上に、いわゆる長期署名の仕組みがあります
  • 本人確認の文脈では「確認を実施した時点で有効だった」ことの記録が確認記録の核になる。犯収法の確認記録としては、確認行為の時点の有効性と、その根拠が残っていることが問われます

証明書の失効はサービス側から見ると例外ではなく日常のイベントです。失効後にユーザーが同じアカウントに戻ってくるまでのフロー設計は証明書の失効とアカウント継続で扱っています。

発注者・レビュー担当者向けチェックリスト

ベンダーの実装や自社の既存コードをレビューするとき、次の項目を順に確認してください。実装者でなくても答え合わせができる粒度にしています。

  • ライブラリ・SDKの「検証成功」が、署名値照合までなのか、チェーンと失効確認まで含むのかをドキュメントで確認したか
  • トラストアンカーをどこから取得し、誰が、どの手順で更新するかが運用文書になっているか
  • 失効確認の対象が署名者証明書だけでなく、チェーン全段になっているか
  • 失効確認の方式(CRL / OCSP)と、CRLの場合の取得間隔・許容する鮮度が決まっているか
  • OCSPのタイムアウト値・リトライ回数・その間のユーザー体験が設計されているか
  • 失効確認ができないときの方針(fail-open / fail-closed)が業務ごとに決まり、文書化されているか
  • fail-openを選ぶ処理について、後追い確認と巻き戻しのフローが実在するか
  • 検証記録に、署名時刻・検証時刻・失効情報の基準時刻の3つが残っているか
  • 失効確認が「行えなかった」ケースも、その事実として記録に残るようになっているか
  • PF経由の場合、PFのSLAと障害時ポリシー、返却されるエラーの意味を契約前に確認したか

このリストの各項目に「はい」と答えられない箇所が、そのまま設計の宿題です。方式選定そのものを含めた全体像はマイナンバーシステム導入支援のページでも整理しています。

まとめ

  • 署名検証には「読めた/署名値が合った/チェーンと失効まで確認した」の3段階があり、業務で意味を持つのは3段階目だけです
  • 検証はチェーン構築→署名値→有効期間→失効確認の4ステップすべてで完成します。トラストアンカーの管理は自社の責任であり、失効確認の対象はチェーン全段です
  • CRL/OCSPは外部依存なので必ず落ちます。fail-open / fail-closedを業務ごとに事前に決め、判断と確認時刻を証跡に残してください
  • 署名時刻・検証時刻・失効時刻を分けて記録します。原則として問われるのは「署名時点で有効だったか」です
  • ライブラリの「verify成功」を鵜呑みにせず、どの段階まで確認しているかをドキュメントで裏取りするのがレビューの起点です

よくある質問

Q. 電子署名の検証は何をどの順番で確認すればよいですか?

チェーン構築→署名値検証→有効期間の確認→失効確認の4ステップです。まず署名者証明書から信頼の起点までの発行者連鎖を構築して各段の署名を検証し、次に対象データのハッシュと署名値を公開鍵で照合し、チェーン上の全証明書が基準時刻に有効期間内かを確認し、最後にCRLまたはOCSPで失効していないかを確認します。この順序でないと、照合した公開鍵が誰のものか分からないまま検証を進めることになります。

Q. 署名値の検証だけでは不十分なのはなぜですか?

署名値の検証は「そのデータがその秘密鍵で署名された」という事実しか示さないためです。攻撃者が自分で鍵ペアを作り、自分で署名し、自分の自己署名証明書を添えて送ってきた場合でも、署名値の照合自体は成功します。信頼できる発行者が出した証明書であること(チェーン構築)と、その証明書が現在も有効であること(有効期間・失効確認)まで確認して、はじめて業務上の意味を持ちます。

Q. CRLとOCSPはどちらを使うべきですか?

用途次第です。CRLは失効リストを定期取得して手元で照合する方式で、キャッシュが効き外部依存を減らせる一方、取得間隔がそのまま失効情報の鮮度の上限になります。OCSPは証明書単位でオンライン照会するため鮮度は高いものの、照会先の遅延や障害が自社の処理時間に直接乗ります。OCSPを採用する場合はタイムアウト値・リトライ回数・その間のユーザー体験を必ず設計してください。

Q. 失効確認ができないとき、取引を通すべきですか止めるべきですか?

業務リスクの判断であり、技術的な正解はありません。口座開設や高額契約のようになりすましの損失が大きい処理はfail-closed(確認できなければ受け付けない)が原則です。停止による業務影響が大きく、事後の確認と巻き戻しが設計できる処理ならfail-openという選択もありえます。最も危険なのは方針を決めていないことで、障害当日に現場判断で通した記録すら残らない事態を招きます。方針・判断者・記録方法を平時に文書化してください。

Q. 署名時刻・検証時刻・失効時刻はなぜ分けて記録する必要があるのですか?

原則として問われるのは「署名時刻において証明書が有効だったか」だからです。署名後に引っ越し等で証明書が失効しても、署名時点で有効であれば署名の効力の前提は保たれます。しかし検証時刻の失効状態だけを記録していると、後日の再検証で失効と表示されたときに「署名時点では有効だった」ことを示せません。署名時刻・検証時刻・参照した失効情報の基準時刻の3つをすべて残してください。

Q. JPKIの失効確認は自社で行えますか?

J-LISへの失効照会を自ら行うには、公的個人認証法に基づく主務大臣の認定が必要です。認定を取得していない事業者は、認定を受けたプラットフォーム事業者のサービスを経由して失効確認を行うことになり、実務ではこちらが一般的です。PF経由の場合は、失効確認が返らない障害時にAPIが何を返し、自社がそれをどう解釈するかを契約前に確認しておく必要があります。

Q. 使っているライブラリが正しく検証しているか、どう確認すればよいですか?

ドキュメントで「verify成功」が示す範囲を確認するのが出発点です。署名値の照合のみを行い、チェーン構築・有効期間・失効確認は呼び出し側の責任としているライブラリは珍しくありません。加えて、トラストアンカーをどこから読み込んでいるか、失効確認の対象が署名者証明書だけか中間CAも含むか、失効情報が取得できなかったときの戻り値が何かの3点を実装で確認してください。

主な参考資料: RFC 5280: X.509証明書とCRLのプロファイルRFC 6960: OCSPJPKI 署名検証者向けページデジタル庁 公的個人認証サービス(JPKI)の導入案内

TodoONada株式会社では、マイナンバーカード認証(JPKI・eKYC)を組み込んだWebサービス・スマホアプリの受託開発を行っています。署名検証フローの設計レビュー、失効確認の障害時ポリシー整理、既存実装が実際にどの段階まで検証しているかの棚卸しといった技術的なご相談にも対応します。方式選定(JPKI・IC読取り・画像方式)から開発・運用までワンストップで支援し、デジタル庁「デジタル認証アプリ」の利用申請・審査対応も書類作成から指摘対応まで伴走します。料金の目安は認証機能組込みプラン150万円〜、認証込みアプリ開発プラン400万円〜、大規模・個別要件は1,000万円〜です。ご相談はマイナンバーシステム導入支援またはお問い合わせからどうぞ。


この記事に関連するサービス

TodoONada株式会社では、マイナンバーカード認証を組み込んだシステム開発を行っています。

導入・開発のご相談はお問い合わせからお気軽にどうぞ。検討段階のご相談も歓迎です。

出典・参照

技術ブログ一覧へ戻る