この特定の場合(github.com)、X509Chain.Build
は、エンド証明書に(発行者情報アクセス拡張内の)発行者証明書の場所に関する情報が含まれているため動作します。
ただし、Thawteが発行者の証明書の所在地に関する明示的な情報を提供しないため、Thawte証明書などでこの機能が動作しないことがあります。また、証明書がローカル証明書ストアにインストールされている場合は、自動的に発行者を見つける方法はありません。 https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx
: -
オプション1 SSL証明書と連携して、SSLセッションを確立することができれば、SSL接続
しかし、あなたはServicePointManager.ServerCertificateValidationCallback
プロパティにリスナーを追加することにより、証明書を取得することができますRemoteCertificateValidationCallbackデリゲートにはいくつかのパラメータがあり、そのうちの1つはchain
です。このパラメータには、サーバによって返されたSSL証明書チェーンが含まれています。リモートサーバーに発行者証明書が含まれている場合は、ChainElements
コレクションにその証明書が表示されます。このオブジェクトは、通常、いくつかの要素が含まれています:ChainElements
は、少なくとも二つの要素(例えば、リーフ証明書と提案発行者)が含まれている場合
- :
-Leaf Certificate
-Issuer Certificate
-(Optional Issuer certs when available)
だから、あなたは二つのことをチェックする必要があります。
ChainElements
コレクションの最初の要素がコレクションにNotSignatureValid
ステータスを持たない場合。 X509Certificate2 issuer = null;
if (
chain.ChainElements.Count > 1 &&
!chain.ChainElements[0].ChainElementStatus.Any(x => x.Status == X509ChainStatusFlags.NotSignatureValid)) {
issuer = chain.ChainElements[1].Certificate;
}
コードのこの部分を実行した後issuer
変数がnull
であれば、あなたは自動的に誰であるかを判断することはできません:あなたはこれらのチェックを実行するためにRemoteCertificateValidationCallback
デリゲートに次のコードを追加することができ
あなたの証明書の発行人。このプロセスにはさらにいくつかの研究が必要です。また、null
ではない場合は、issuer
変数に実際の発行者証明書が保持されます。
オプション2 - 検索
は、[OK]を、あなたのコメントによると、あなたは発行者証明書は、ローカル証明書ストアにインストールされているかどうかを判断するローカル証明書ストア。あなたの質問を読んで、私はそれを得ていませんでした。なぜあなたは実際にあなたが探しているものを推測する必要がありますか?最終的には、あなたが達成したいことを知っているか理解しているかどうかはまだ分かりません。見つける)
1)X509Certificate2Collection.Findメソッドを使用し、そのサブジェクト名
2で候補証明書を見つける:あなたは、発行者がローカルストアにインストールされているかどうかを検索したい場合は
は、次のアルゴリズムを使用することができます(ステップ1で検索された)候補リストにおいて、サブジェクト内の証明書のオーソリティ・キー識別子値と同じサブジェクト・キー識別子値を有するもの。対象におけるcert
変数を格納する証明書(そのために発行者を検索する)と仮定
X509Certificate2Collection certs = new X509Certificate2Collection();
// grab candidates from CA and Root stores
foreach (var storeName in new[] { StoreName.CertificateAuthority, StoreName.Root }) {
X509Store store = new X509Store(storeName, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
certs.AddRange(store.Certificates);
store.Close();
}
certs = certs.Find(X509FindType.FindBySubjectDistinguishedName, cert.Issuer, false);
if (certs.Count == 0) {
Console.WriteLine("Issuer is not installed in the local certificate store.");
return;
}
var aki = cert.Extensions["2.5.29.35"];
if (aki == null) {
Console.WriteLine("Issuer candidates: ");
foreach (var candidate in certs) {
Console.WriteLine(candidate.Thumbprint);
}
return;
}
var match = Regex.Match(aki.Format(false), "KeyID=(.+)", RegexOptions.IgnoreCase);
if (match.Success) {
var keyid = match.Groups[1].Value.Replace(" ", null).ToUpper();
Console.WriteLine("Issuer candidates: ");
foreach (var candidate in certs.Find(X509FindType.FindBySubjectKeyIdentifier, keyid, false)) {
Console.WriteLine(candidate.Thumbprint);
}
} else {
// if KeyID is not presented in the AKI extension, attempt to get serial number from AKI:
match = Regex.Match(aki.Format(false), "Certificate SerialNumber=(.+)", RegexOptions.IgnoreCase);
var serial = match.Groups[1].Value.Replace(" ", null);
Console.WriteLine("Issuer candidates: ");
foreach (var candidate in certs.Find(X509FindType.FindBySerialNumber, serial, false)) {
Console.WriteLine(candidate.Thumbprint);
}
}
。このアプローチには、シグネチャを検証しないために偽陽性を返す可能性があるため、問題があります。
[閉鎖についてのメタ質問](http://meta.stackoverflow.com/q/317570/1364007)のとおり、私はそこで詳細に答えます。返信するのに数分かかります。 –
私は[回答済み](http://meta.stackoverflow.com/a/317581/1364007)です。遅延のお詫び –
IssuerName'プロパティの何が問題なのですか? – erickson