Windows 秘密キーの有効期間の簡素化
PersistKeySet または EphemeralKeySet ストレージ オプションを設定せずに Windows 上でワークロードに PKCS#12/PFX が読み込まれると、秘密キーがいつ不要になり消去する必要があるかを .NET が判断します。 以前のバージョンの .NET (および .NET Framework) では、2 種類のロジック セットが使用されていました。 .NET 9 で使用されるロジック セットは 1 種類のみです。
以前の動作
以前は、new X509Certificate2(pfx, password, flags)
を使用して PKCS#12/PFX から証明書 (およびその秘密キー) を読み込む際に、読み込まれる証明書が秘密キーの有効期間を表していました。 この証明書オブジェクトが破棄 (破棄されずにガベージ コレクションされた場合は最終化) されるときに、関連する秘密キーが削除されていました。 所有権の共有や所有権の移転は発生しませんでした。
X509Certificate2Collection.Import(pfx, password, flags)
を使用して PKCS#12/PFX から証明書 (およびその秘密キー) を読み込む際には、単一の証明書を読み込む場合と同様に、秘密キーを持つ各証明書が有効期間を追跡していました。 ただし、単一の証明書の場合に加えて、証明書のネイティブ コピーにマーカーが配置され、いずれのコピーでも秘密キーの有効期間を追跡する必要があることが示されていました。 2 番目の X509Certificate2 オブジェクトが、同じ PCERT_CONTEXT
値に基づいて作成された場合、先に破棄 (または最終化) されたコピーによって、他のコピーの秘密キーが消去されます。
秘密キーが削除されるため、次のコードは (CryptographicException または NullReferenceException で) 失敗となっていました。
X509Certificate2Collection coll = new X509Certificate2Collection(pfx, password, X509KeyStorageFlags.DefaultKeySet);
X509Certificate2Collection coll2 = coll.Find(X509FindType.FindBySubjectName, "", false);
coll2 = null;
GC.Collect();
GC.WaitForPendingFinalizers();
using (RSA key = coll[0].GetRSAPrivateKey())
{
key.SignData(pfx, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
}
新しい動作
.NET 9 以降では、有効期間は常に PKCS#12/PFX 読み込みから直接生成された X509Certificate2 インスタンスに関連付けられます。
「以前の動作セクション」の同じコード スニペットが成功するようになりました。
導入されたバージョン
.NET 9 Preview 7
破壊的変更の種類
この変更は、動作変更です。
変更理由
PKCS#12/PFX を読み込むほとんどのワークロードでは、単一の証明書読み込みが使用され、その方法に関連付けられている有効期間のしくみが認識されています。 コレクションの読み込みに関連するメカニズムは、予想外のものであることが多く、場合によってはキーの早期消去につながっていました。
推奨される操作
コレクション読み込みの有効期間管理を理解したうえで、クローンに対して Dispose
を呼び出すことでキーの消去を実行していた場合は、元の読み込まれたオブジェクトに対しても Dispose
を呼び出していることを確認してください。
影響を受ける API
.NET