私は、.net / c# 経由でクライアント認証証明書を発行するために使用している Windows 証明機関を持っています。証明機関の API を COM 経由で呼び出すことで、プログラムで証明書を発行することに成功しました。クライアントをセットアップするときに、新しい証明書を発行します。
実行時に、これらのクライアントはサーバーへのリクエストに証明書を添付します。X509Certificate2 が証明機関のルート証明書によって署名されたことをプログラムで確認し、他のソースによって署名された証明書を拒否するにはどうすればよいでしょうか。
ベストアンサー1
私はこれをやったたくさんここに、使用できる簡単なコードをいくつか示します。
ブロック内の部分はif (!isChainValid)
、きれいなエラー メッセージを作成するためのものです。必要なければ使用する必要はありませんが、チェーンを構築できない場合はエラーをスローする必要があります。チェーン要素は、ルートを確認するために必要です。
X509Certificate2 authority = GetAuthorityCertificate();
X509Certificate2 certificateToValidate = GetCertificateToValidate();
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
// This part is very important. You're adding your known root here.
// It doesn't have to be in the computer store at all. Neither certificates do.
chain.ChainPolicy.ExtraStore.Add(authority);
bool isChainValid = chain.Build(certificateToValidate);
if (!isChainValid)
{
string[] errors = chain.ChainStatus
.Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))
.ToArray();
string certificateErrorsString = "Unknown errors.";
if (errors != null && errors.Length > 0)
{
certificateErrorsString = String.Join(", ", errors);
}
throw new Exception("Trust chain did not complete to the known authority anchor. Errors: " + certificateErrorsString);
}
// This piece makes sure it actually matches your known root
var valid = chain.ChainElements
.Cast<X509ChainElement>()
.Any(x => x.Certificate.Thumbprint == authority.Thumbprint);
if (!valid)
{
throw new Exception("Trust chain did not complete to the known authority anchor. Thumbprints did not match.");
}