14.4.6. 運用:鍵、有効期限、トラブルシューティング

証明書に関する作業は、デプロイされたすべてのデバイスにおいて3つの側面にまたがります。すなわち、カメラ上に置かれた秘密鍵の保護、証明書が期限切れになる日への備え、そして実際に発生するエラーモードの短いリストです。

14.4.6.1. 秘密鍵の保護

カメラが証明書を提示するとき(TLSサーバーとして、またはmTLSのクライアントとして)、その秘密鍵はプレーンなDER形式で、ファイルシステムまたはROMFS上のデバイス内に存在しなければなりません。そのように保存された鍵は、カメラ上で実行されるあらゆるコードからも、物理的にアクセスできる者からも読み取り可能です。USBマスストレージドライブ、REPLプロンプト、あるいは生のフラッシュからも読み取れます。ROMFSや読み取り専用フラグは改変を防ぎますが、抽出は防ぎません。デバイス上に出荷した秘密鍵は、物理的またはコード的アクセスを持つ意志の固い攻撃者によって復元可能であると見なしてください。

これはTLSを無意味にするものではなく、TLSをどう運用するかを形作るものです。

  • デバイスごとに一意の鍵と証明書を使用してください。 共有の鍵を機器群全体にフラッシュしてはいけません。1台から鍵が抽出されれば、攻撃者はすべてのカメラになりすませてしまいます。デバイスごとの鍵であれば、侵害をその1台に留められ、サーバー側で失効または無効化できます。

  • 証明書は短命にしてください。 盗まれた鍵が役立つのは、その証明書が有効な間だけです。短い有効期間と定期的なローテーションが被害の範囲を限定します(後述の 証明書の有効期限とローテーション を参照)。

  • 可能な限り、そもそもデバイスに秘密情報を置かないでください。 サーバーの検証のみが必要な場合(mTLSではなくサーバー認証)、クライアントとしてのカメラはCA証明書(これは公開情報です)のみを保存し、盗む価値のある秘密鍵を一切持ちません。

  • 公開ファームウェアイメージに鍵を含めて出荷しないでください。 配布するファームウェアビルドのROMFSに焼き込まれた鍵は秘密ではありません。そのファームウェアをダウンロードした誰もがそれを手にします。デバイスごとのプロビジョニングとは、汎用ファームウェアのに鍵をプログラムすることを意味し、その中に含めることではありません。

  • 影響範囲を限定してください。 証明書が認証する対象を限定し(最小権限)、漏洩した単一のデバイスIDを、残りに影響を与えずに失効または無効化できるようにしてください。

脅威モデルに物理的アクセスを持つ攻撃者が含まれる場合は、デバイスの鍵はいずれ漏洩するという前提で設計し、それが致命的にならないようにしてください。そうする機能を持たないハードウェア上で鍵を秘密に保てると仮定するのではなく。

14.4.6.2. 証明書の有効期限とローテーション

すべての証明書には有効期間が付随します。それを過ぎると、ssl.CERT_REQUIRED のピアは接続を拒否します。つまり有効期限は理論上のリスクではなく、現実にスケジュールされた停止です。有効性チェックを正しく評価するには、カメラのクロックも正確でなければなりません。

  • 自己署名。 有効期間は -days で選択しました。期限が切れたら、鍵/証明書を再生成して再デプロイする必要があります。DERファイルを再コピーするか、証明書が焼き込まれている場合はROMFSイメージを再ビルドして再フラッシュします。実際に対応を覚えていられる -days の値を選んでください。

  • 公開CA。 これらは意図的に短命です。Let's Encryptは90日間の証明書を発行し、おおよそ60日ごとの自動更新を期待しています。「一度インストールしたら忘れる」という選択肢はありません。

より大きな潮流は一方向です。公的に信頼されるTLS証明書の最大有効期間は縮小し続けています。かつては825日、現在は398日が上限であり、CA/Browser Forumは2029年までにおおよそ47日へと段階的に引き下げるスケジュールを採用しました。デバイス設計への教訓は、証明書は短命であり、ローテーションは自動化されるか少なくとも定型化されなければならないと想定することです。10年有効な証明書を人間が交換することに依存する製品を出荷してはいけません。

実際にカメラ上では、再フラッシュなしで証明書を置き換えられる設計(書き込み可能なファイルシステムとリモート更新の経路、あるいは中央でローテーションするCAを信頼するクライアントとしてカメラを動作させる)を優先してください。証明書をROMFSに置かざるを得ない場合は、その有効期間に合わせてファームウェア更新をスケジュールしてください。

14.4.6.3. トラブルシューティング

  • クロックが設定されていなければなりません。 電源投入以降クロックを設定していないカメラは証明書の有効性チェックに失敗します。まず ntptime.settime() を呼び出してください。

  • ホスト名が一致しなければなりません。 クライアントが server_hostname を渡すとき、それは証明書の subjectAltName(古いスタックでは CN)と一致しなければならず、そうでなければ検証は失敗します。

  • 形式が誤っている。 カメラにコピーしたPEMファイルは読み込まれません。先にDERに変換してください。

  • 証明書の期限切れ。 以前は動作していた接続が OSError で失敗するようになった場合、単に証明書が期限切れである可能性があります。有効期日を確認し、必要に応じて再生成/再デプロイしてください。

  • Ed25519鍵は失敗します。 Ed25519ではなく、ECDSA P-256/P-384またはRSAを使用してください。

  • エラーは OSError です。 MicroPythonは ssl.SSLError を実装していません。TLSの失敗(不正な証明書、期限切れ、不明なCA、形式エラー、ハンドシェイク失敗)はすべて OSError として発生します。