一覧SC-07-4 · 公開鍵と電子署名

暗号の利用状況の把握と移行計画

何を、誰と、どのデータを残しながら変更する必要があるかを台帳から整理します。

説明

暗号方式を変更するときは、アルゴリズム名だけでなく、用途、データを守る期間、鍵の保存先、相手側の対応状況を調べます。保存済みの暗号文や署名を扱う仕組みも移行対象になり得ます。

固定の資産台帳をSQLで調べ、長期保存の文書から鍵の保護方式まで依存をたどります。提案済みの方式と相手の対応表を突き合わせ、設定名の変更だけでは移行完了にならないことを確認します。

何を、誰と、どのデータを残しながら変更する必要があるかを台帳から整理します。

1資産を用途別に調べる

retentionはこの架空組織が定めた保持年数です。方式ごとの推奨期限ではありません。

from sc07 import inventory db = inventory() print(db.execute("SELECT * FROM assets ORDER BY id用途・方式・期間・所有者を一覧にする").fetchall())

本文のAES、鍵配送のRSA、鍵交換のX25519、署名のEd25519が別の資産です。すべてを一つの方式名へ一括置換する構成ではありません。

2長く保護する情報を抽出する

この例では10年以上の保持対象を先に調査する運用方針とします。

print(db.execute("SELECT id,purpose,retention FROM assets WHERE retention>=10この例の優先調査条件で抽出する ORDER BY id").fetchall())

archive・sign・wrapが該当します。保管期間に加え、移行に要する時間や記録済み通信の将来の解読も検討対象です。

3本文から鍵の依存先をたどる

archiveがwrapへ、wrapがkmsへ依存しています。再帰問合せで経路を列挙します。

print(db.execute("WITH RECURSIVE deps(id)依存先を再帰的にたどる AS (SELECT 'archive' UNION SELECT e.child FROM edges e JOIN deps d ON e.parent=d.id) SELECT id FROM deps ORDER BY id").fetchall())

本文がAESでも、鍵の配送・保存には別方式が使われています。本文の方式だけで将来の保護を判断できません。

4提案と相手の対応状況を照合する

提案欄の方式名はこの架空計画の候補です。プロトコルの具体的な組合せや実装方式は別途検証が必要です。

print(db.execute("SELECT p.asset,p.algorithm,e.child,s.ready移行案と依存先の対応状況を結合する FROM proposed p JOIN edges e ON p.asset=e.parent JOIN support s ON e.child=s.component ORDER BY p.asset").fetchall())

clientとkmsは未対応の0、verifierだけ対応済みの1です。送信側や保存側だけ変更しても利用できるとは限りません。

5対応済みの依存先だけを抽出する

変更を進める前に、未対応の依存が残る資産を除きます。

query = "SELECT p.asset FROM proposed p WHERE NOT EXISTS未対応の依存先がないことを条件にする (SELECT 1 FROM edges e JOIN support s ON e.child=s.component WHERE e.parent=p.asset AND s.ready=0) ORDER BY p.asset" print(db.execute(query)条件に合う資産を抽出する.fetchall())

この固定台帳ではsignだけです。これは対応表による抽出であり、性能や相互接続試験まで合格したという意味ではありません。

6KMSの対応状況を更新する

検証済みの対応表を受領したという設定でkmsを1へ更新します。アルゴリズム名はまだ変更しません。

db.execute("UPDATE support SET ready=1依存先の対応状況を更新する WHERE component='kms'") print(db.execute(query).fetchall()) print(db.execute("SELECT algorithm FROM assets現行方式を確認する WHERE id='wrap'").fetchone())

候補へwrapが増えますが、現在の資産はまだRSA-2048です。準備完了と切替済みを別に記録する必要があります。

7旧データの取扱いを残す

移行後も保持期限内の旧暗号文を復号する必要があります。現行の保持対象を所有者へ結び付けます。

print(db.execute("SELECT a.id,a.retention,a.owner,e.child旧データの期間・責任者・依存を対応付ける FROM assets a JOIN edges e ON a.id=e.parent WHERE a.id IN ('archive','wrap') ORDER BY a.id").fetchall())

recordsとplatformが、旧文書と鍵保護の移行を調整する必要があります。再暗号化、再ラップ、旧鍵の期限付き保持のどれを使うかは保存形式と運用条件に応じて決めます。

まとめ

暗号資産は用途・保持期間・所有者・依存先を含めて管理します。

対応表の更新と実際の切替は別の状態です。

新規データの方式変更だけでなく、旧データを扱う計画も必要です。

操作履歴と解説を振り返れます。

Python 3.15 / cryptography 50.0.2 / 公開試料と固定時刻

1
from sc07 import inventory db = inventory() print(db.execute("SELECT * FROM assets ORDER BY id").fetchall())
[('archive', 'encryption', 'AES-256-GCM', 15, 'records'), ('sign', 'signature', 'Ed25519', 10, 'release'), ('web', 'key-exchange', 'X25519', 1, 'web-team'), ('wrap', 'key-transport', 'RSA-2048', 15, 'platform')]
2
print(db.execute("SELECT id,purpose,retention FROM assets WHERE retention>=10 ORDER BY id").fetchall())
[('archive', 'encryption', 15), ('sign', 'signature', 10), ('wrap', 'key-transport', 15)]
3
print(db.execute("WITH RECURSIVE deps(id) AS (SELECT 'archive' UNION SELECT e.child FROM edges e JOIN deps d ON e.parent=d.id) SELECT id FROM deps ORDER BY id").fetchall())
[('archive',), ('kms',), ('wrap',)]
4
print(db.execute("SELECT p.asset,p.algorithm,e.child,s.ready FROM proposed p JOIN edges e ON p.asset=e.parent JOIN support s ON e.child=s.component ORDER BY p.asset").fetchall())
[('sign', 'ML-DSA', 'verifier', 1), ('web', 'hybrid-key-exchange', 'client', 0), ('wrap', 'ML-KEM', 'kms', 0)]
5
query = "SELECT p.asset FROM proposed p WHERE NOT EXISTS (SELECT 1 FROM edges e JOIN support s ON e.child=s.component WHERE e.parent=p.asset AND s.ready=0) ORDER BY p.asset" print(db.execute(query).fetchall())
[('sign',)]
6
db.execute("UPDATE support SET ready=1 WHERE component='kms'") print(db.execute(query).fetchall()) print(db.execute("SELECT algorithm FROM assets WHERE id='wrap'").fetchone())
[('sign',), ('wrap',)]
('RSA-2048',)
7
print(db.execute("SELECT a.id,a.retention,a.owner,e.child FROM assets a JOIN edges e ON a.id=e.parent WHERE a.id IN ('archive','wrap') ORDER BY a.id").fetchall())
[('archive', 15, 'records', 'wrap'), ('wrap', 15, 'platform', 'kms')]

演習完了