ローカルマシンの証明書ストアにX509証明書(pfx/PKCS#12)をプログラムでインポートしようとしています。この特定の証明書には証明書のチェーンがあり、証明書のパスは次のようになります。
私が使用するコードは次のようになります:
cert = new X509Certificate2(pathToCert, password);
if (cert != null)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
if (!store.Certificates.Contains(cert))
{
store.Add(cert);
}
}
このコードは証明書をインポートしますが、チェーンを無視しているようです。ストアで証明書を確認すると、証明書のパスには次の情報しか表示されません。
ただし、pfxを手動でインポートすると、完全なパスが表示されます。ここでステップをスキップしていますか、それとも一部のパラメータが不足していますか?誰かがこれに光を当てることができますか?
X509Certificate2CollectionオブジェクトとしてPFXファイルを開くことにより、PFX内の証明書を反復処理(およびそれぞれを選択した証明書ストアにインポート)できるはずです。
X509Certificate2Collectionのドキュメントは次のとおりです。
MSDNは、コレクション内の各証明書を検査する方法について、そのドキュメントページにサンプルコードをいくつか提供しています。
各証明書に関するCN /発行者/その他の情報がわかったら、各証明書を追加する必要がある証明書ストアを明確にする必要があります。そのために、X509StoreクラスとStoreName列挙を使用して、開く/追加するストアを指定できます。
http://msdn.Microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx
http://msdn.Microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename.aspx
同様のSO質問への私の回答も参照してください:
その回答に関する最新のコメントの1つで述べたように、現在のユーザーのルートストア(名前/場所として「StoreName.Root」および「StoreLocation.CurrentUser」)に証明書をインポートしようとすると、ポップアップダイアログが表示されます。確認してください。
この問題を解決するには、証明書のインポートメソッドに小さなMS UIオートメーションコードを追加し、プロンプトで[OK]をクリックします。
または、コメンター「CodeWarrior」が他のSO回答のコメントで述べているように、ポップアップダイアログを回避するには、ルート証明書をCurrentUserではなくLocalMachineストアに配置してみてください。
サンプルコード:
string certPath = <YOUR PFX FILE PATH>;
string certPass = <YOUR PASSWORD>;
// Create a collection object and populate it using the PFX file
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet);
foreach (X509Certificate2 cert in collection)
{
Console.WriteLine("Subject is: '{0}'", cert.Subject);
Console.WriteLine("Issuer is: '{0}'", cert.Issuer);
// Import the certificate into an X509Store object
}
今後の参考のために、X509Chainオブジェクトを使用してこれを行う別の方法を発見しました。
var cert = new X509Certificate2(pathToCert, password);
X509Chain chain = new X509Chain();
chain.Build(cert);
for (int i = 0; i < chain.ChainElements.Count; i++)
{
//add to the appropriate store
}
「適切な店舗へ」のコードの一般的なソリューションを希望する人のために
これは、VBを使用して作成したものなので、C#に移植するのは難しいことではありません。上記の投稿を使用して始めました。私はこれでNooBになりました。
Dim certPath = "C:\Users\08353153\Documents\Visual Studio 2015\Projects\WindowsApplication2\WindowsApplication2\bin\Debug\8870-thebigchess.pfx"
Dim certPass = "eduSTAR.NET"
Dim Collection As New X509Certificate2Collection
Collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet)
Dim certOne As X509Certificate2 = Collection(0)
Dim certTwo As X509Certificate2 = Collection(2)
Dim certThree As X509Certificate2 = Collection(1)
Dim personal As New X509Store(StoreName.My, StoreLocation.LocalMachine)
personal.Open(OpenFlags.ReadWrite)
personal.Add(certOne)
personal.Close()
Dim trust As New X509Store(StoreName.Root, StoreLocation.LocalMachine)
trust.Open(OpenFlags.ReadWrite)
trust.Add(certTwo)
trust.Close()
Dim intermed As New X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine)
intermed.Open(OpenFlags.ReadWrite)
intermed.Add(certThree)
intermed.Close()
X.509証明書には、ルート証明書(中間認証局を含む)にリンクするチェーンのみが含まれていますが、これらの証明書は証明書に含まれていません。このチェーンは、(自己署名されていない)エンド証明書が検証されるときに使用されます-信頼されるルート証明書につながる必要があります。より正確には、各CAの公開鍵を使用して、発行された証明書のハッシュをデコードおよび検証します。このプロセスは、ルート証明書に到達するまで繰り返されます。チェーン全体がチェックされた後、ルート証明書が信頼されている場合、エンド証明書も信頼されます。もちろん、プロセスには他の検証(開始日、終了日、証明書失効リストなど)も含まれますが、ここではチェーンの使用に関連する部分のみを詳しく説明しました。
したがって、「ルート証明書CA」へのチェーンと一緒に「マイ証明書」を正しくインポートしました-このチェーンは「マイ証明書」にエンコードされており、プロパティを表示することでこれを確認できますが、このチェーンはリンクにすぎず、 「ルート証明書CA」、「組織証明書CA」、「組織2証明書CA」のいずれかの証明書が含まれています。
これで問題が解決することを願っていますが、解決しない場合は、何を達成しようとしているのか具体的に説明できますか?