代表的な面接トピック

コーディング面接:Go 1.26 の crypto/hpke を使用してローテーション可能なエンベロープ暗号化をどのように設計しますか?

コーディング難しい
Offer.cc 編集チーム公開日 更新日

質問

Go 1.26 の crypto/hpke を使用して、機密性の高いマルチテナント設定を暗号化してください。鍵ローテーション、古い暗号文の読み取り、テナント分離、および改ざん検知をサポートします。モード選択、コンテキストバインディング、鍵ライフサイクル、およびテストについて説明してください。

プロンプトとコンテキスト

マルチテナント設定サービスは、機密性の高いデータベース値を暗号化する必要があります。各テナントには独立した論理鍵があります。プラットフォームはルート鍵をローテーションし、古い暗号文を読み取り、テナント間またはレコード間でコピーされた暗号文を検知できなければなりません。Go 1.26 の crypto/hpke を使用して、エンベロープ、暗号化/復号フロー、鍵バージョン、コンテキストバインディング、および移行を設計してください。中核となるスキルは暗号 API の適切な構成とライフサイクル設計であるため、これは coding の質問です。

面接官が評価するポイント

第 1 に、HPKE KEM、KDF、および AEAD の役割を理解し、公開鍵カプセル化と対称データ暗号化を区別できているか。

第 2 に、Base、PSK、または Auth モードを選択し、認証鍵と機密性鍵の境界を説明できるか。

第 3 に、コンテキストをまたいだ復号を防ぐために、テナント、用途、スイート、およびバージョンが info または AAD にバインドされているか。

第 4 に、バージョン番号を秘密情報として扱うことなく、ローテーション、古いバージョンの読み取り、失効、および再暗号化が設計されているか。

第 5 に、改ざん、リプレイ、乱数性、障害情報、および相互運用性のテストによって実装が検証されているか。

最初に明確にすべき質問

  • 機密性だけで十分か、それとも送信者を暗号学的に認証する必要があるか?
  • 受信者の公開鍵を所有しているのは誰か、また KMS、HSM、監査の要件はあるか?
  • 古い暗号文はどのくらいの期間残り、バックグラウンドでの再暗号化が必要か?
  • テナントと設定鍵の関係は可視メタデータとして許可されるか?
  • 他言語での復号やオフラインリカバリは必要か?
  • 鍵の欠落、未サポートバージョン、認証失敗を区別できるようにすべきか?

30秒で答える要約

「RFC 9180 スイートと Go 1.26 を固定します。サービスは各テナントの受信者秘密鍵を保持し、アプリケーションはその公開鍵を使用してカプセル化します。エンベロープにはスイートと鍵バージョンが保存され、テナントと用途は info に、テナント、鍵、レコードバージョンは AEAD AAD にバインドされます。復号時はエンベロープのバージョンによって古い秘密鍵を選択します。新規書き込みにはローテーション後のバージョンを使用し、バックグラウンドジョブで古いデータを再暗号化します。Auth は送信者の証明が必要な場合にのみ選択します。テストでは改ざん、テナント間の入れ替え、リプレイ、乱数性、古いバージョン、他言語ベクトルを網羅します。」

詳細な解決策

ステップ 1: エンベロープ層を分離する

HPKE は KEM で共有シークレットを確立し、KDF で鍵を導出し、AEAD でメッセージを暗号化します。エンベロープには、スイート、鍵バージョン、カプセル化された素材、nonce またはシリアライズされた暗号文、およびパブリックメタデータが格納されます。ルート鍵および受信者秘密鍵は KMS または HSM に保持し、暗号文やアプリケーションログには絶対に出力しません。

ステップ 2: モードとアイデンティティセマンティクスを選択する

Base モードは、送信者認証なしで受信者公開鍵暗号化を提供します。PSK は事前共有鍵を追加します。Auth は送信者鍵を使用して送信元を認証します。プラットフォームのログインアイデンティティは、HPKE が送信者を認証したことを意味するわけではありません。認可と暗号モードは別個のレイヤーです。

ステップ 3: コンテキストをバインドする

プロトコル、サービス、バージョン、および用途を info にバインドします。エンベロープとともに転送され完全性を維持する必要がある場合は、テナント ID、設定鍵、およびレコードバージョンを AEAD AAD にバインドします。復号時に同じ入力が再計算されるため、テナント、用途、またはバージョンが入れ替えられると認証に失敗します。

text
envelope = suite_id | key_version | encapsulated_key | aad_fields | ciphertext
info = "config-envelope/v1" | tenant_scope | purpose
aad = tenant_id | config_key | record_version

ステップ 4: 鍵ライフサイクルを設計する

各鍵バージョンには、作成時刻、状態、復号スコープ、および破棄ポリシーがあります。書き込みを切り替える前に新しい公開鍵を公開し、読み取り時はエンベロープのバージョンによって古い秘密鍵を選択します。再暗号化と監査チェックが完了するまで古いバージョンを読み取り専用として保持し、その後に失効させます。

ステップ 5: リプレイとシリアライゼーションを処理する

AEAD は改ざんを検知しますが、有効な古い暗号文が再送信されるのを防ぐことはできません。設定にバージョンや単調増加シーケンスがある場合、ビジネスレイヤーで期待されるバージョンをチェックします。明示的な長さ、バージョン、スイートのフィールドを使用し、未知のスイート、切り詰め、重複フィールドを拒否します。

ステップ 6: エラー境界を定義する

外部には一様な復号失敗を返します。内部的には構造化された理由と鍵バージョンを監査ログに記録し、秘密鍵、平文、完全な暗号文は記録しません。鍵の欠落、未サポートフォーマット、認証失敗の区別は運用に役立ちますが、信頼できない呼び出し元に対してタイミングやメッセージからテナントや鍵の存在を推測させてはなりません。

ステップ 7: テストと移行を構築する

固定された RFC ベクトル、乱数性、1バイト改ざん、テナント間 AAD、古いバージョンの読み取り、並行ローテーション、失効後の失敗、および大きなメッセージのチャンク化をテストします。他言語システムには共有シリアライゼーションとベクトルが必要です。1.26 未満のサービスは互換ラッパーまたはアップグレードゲートを使用し、実験的 API が誤って本番環境に入らないようにします。

質の高い回答例

「HPKE をエンベロープ層として使用します。KEM と KDF で共有鍵を確立・導出し、AEAD で設定平文を保護します。エンベロープにはスイート、鍵バージョン、カプセル化素材、暗号文が含まれ、テナント間コピーを防ぐためにテナント、用途、鍵、レコードバージョンが info と AAD を通じてバインドされます。Base は受信者の機密性のみを提供するため、送信者証明が必要な場合は Auth または外部署名を選択します。ローテーションではまず新バージョンを書き込み、旧バージョンを読み取り専用に保ち、バックグラウンドで再暗号化した後、検証を経て失効させます。AEAD はリプレイを防がないため、ビジネスバージョンを検証します。秘密鍵は KMS/HSM に保持し、テストには改ざん、失効、エラー、他言語ベクトルを含めます。」

よくある間違い

  • Base を送信者認証として扱う → 受信者は誰が送信したかを証明できません → Auth または外部署名を使用します。
  • テナントを可視メタデータにのみ配置する → 攻撃者がテナント間で暗号文を入れ替えることができます → info または AAD にバインドします。
  • ローテーション直後に古い鍵を削除する → 過去のデータが読み取り不能になります → 読み取り専用ウィンドウを維持し、まず再暗号化します。
  • AEAD がリプレイを防ぐと思い込む → 有効な古い暗号文が再送信される可能性があります → ビジネスバージョンやシーケンスをチェックします。
  • 秘密鍵を設定やログに保存する → 暗号化境界が破壊されます → KMS/HSM と最小権限を使用します。
  • バージョン管理のないバイナリフォーマットを独自作成する → 移行やスイートの拒否が安全に行えなくなります → 明示的なバージョン、長さ、スイートをエンコードします。
  • 詳細な復号エラーを返す → テナントや鍵の存在が漏洩する可能性があります → 外部には一様なエラーを返し、内部で監査します。
  • 成功ケースのみをテストする → 改ざんや旧バージョンの障害が本番に混入します → ベクトル、クロスコンテキスト、失効テストを追加します。

フォローアップの質問

フォローアップ 1: なぜすべての平文を RSA や ECDH で直接暗号化しないのですか?

HPKE は KEM、KDF、AEAD を明示的に構成しており、対称セッション鍵のカプセル化や大きなメッセージの処理に適しています。任意の平文を直接公開鍵暗号化すると、長さ、乱数性、モードの誤用を招きやすくなります。

フォローアップ 2: Auth モードはどのような場合に適していますか?

既知の送信者鍵が関与したことを受信者が暗号学的に証明する必要がある場合に Auth を使用します。受信者の機密性のみが必要な場合は、管理されていない認証鍵を追加しないでください。

フォローアップ 3: info と AAD の違いは何ですか?

info は鍵導出に参加し、プロトコルコンテキストを定義します。AAD は可視のままですが AEAD によって完全性が保護されるため、復号時に一致する必要があるエンベロープメタデータに適しています。

フォローアップ 4: 安全に再暗号化するにはどうすればよいですか?

冪等なトランザクションまたはリトライ可能なワークフローで、古いバージョンを読み取り、新しいバージョンを書き込みます。新しい暗号文が復号・再読み取りおよび監査チェックに合格した後にのみ、古い鍵を失効させます。

フォローアップ 5: 暗号文が別のレコードに移動するのを防ぐにはどうすればよいですか?

テナント、設定鍵、レコードバージョン、用途を AAD に配置し、読み取り時に現在のデータベース値から AAD を再構築します。コピーされたエンベロープは認証タグの検証で失敗します。

フォローアップ 6: HPKE は前方秘匿性(Forward Secrecy)を提供しますか?

その性質は鍵ライフサイクルとモードに依存します。長寿命の静的受信者秘密鍵を使用する場合、過去の暗号文の保護はその鍵に依存します。より強力な前方秘匿性には、一時鍵、ローテーション、破棄、およびプロトコルレベルのセッションが必要です。API 名だけで提供されるものではありません。

公開情報ソース

関連する質問

関連面接ツール

コーディング問題にはスクリーンショットを使用

問題をキャプチャし、制約条件、解法アプローチ、コード、エッジケース、計算量の順に進めます。

ツールを見る