Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何验证证书是由特定的证书颁发机构创建的?_C#_.net_Security_Certificate - Fatal编程技术网

C# 如何验证证书是由特定的证书颁发机构创建的?

C# 如何验证证书是由特定的证书颁发机构创建的?,c#,.net,security,certificate,C#,.net,Security,Certificate,我有一个Windows证书颁发机构,用于通过.net/c#颁发客户端身份验证证书。通过COM调用证书颁发机构的API,我已经成功地让它以编程方式颁发证书。我在设置客户端时颁发新证书 在运行时,这些客户端将证书附加到服务器的请求。如何以编程方式验证X509Certificate2是否由我的证书颁发机构的根证书签署(并拒绝由任何其他来源签署的证书)?如果您说您有根(自签名)证书,那么您唯一的选择就是在服务器上保持此根证书可用(当然没有私钥)并对根证书执行证书验证过程。这是web客户端验证服务器证书链

我有一个Windows证书颁发机构,用于通过.net/c#颁发客户端身份验证证书。通过COM调用证书颁发机构的API,我已经成功地让它以编程方式颁发证书。我在设置客户端时颁发新证书


在运行时,这些客户端将证书附加到服务器的请求。如何以编程方式验证X509Certificate2是否由我的证书颁发机构的根证书签署(并拒绝由任何其他来源签署的证书)?

如果您说您有根(自签名)证书,那么您唯一的选择就是在服务器上保持此根证书可用(当然没有私钥)并对根证书执行证书验证过程。这是web客户端验证服务器证书链的镜像情况。

我已经做了很多这方面的工作。。下面是一些简单的代码,您可以使用

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.");
}
X509Certificate2 authority=GetAuthorityCertificate();
X509Certificate2 certificateToValidate=GetCertificateToValidate();
X509Chain chain=新的X509Chain();
chain.ChainPolicy.RevocationMode=X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag=X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags=X509VerificationFlags.AllowUnknownCertificationAuthority;
chain.ChainPolicy.VerificationTime=DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout=新的时间跨度(0,0,0);
//这部分非常重要。您正在此处添加已知根。
//它根本不必在计算机商店里,证书也不必。
chain.ChainPolicy.ExtraStore.Add(权限);
bool isChainValid=chain.Build(certificateToValidate);
如果(!isChainValid)
{
字符串[]错误=chain.ChainStatus
.Select(x=>String.Format(“{0}({1})”,x.StatusInformation.Trim(),x.Status))
.ToArray();
字符串certificateErrorsString=“未知错误。”;
if(errors!=null&&errors.Length>0)
{
certificateErrorsString=String.Join(“,”,错误);
}
抛出新异常(“信任链未完成到已知的权限锚点。错误:“+CertificateErrorString”);
}
//这一部分确保它实际上与您已知的根匹配
var valid=chain.ChainElements
.Cast()
.Any(x=>x.Certificate.Thumbprint==authority.Thumbprint);
如果(!有效)
{
抛出新异常(“信任链未完成到已知的权限锚点。指纹不匹配。”);
}

对于
X509Certificate2
,也可以使用内置方法
Verify()

X509Certificate2 certificateToValidate = GetCertificateToValidate();
bool valid = certificateToValidate.Verify()

应该在security.se上(可能)为什么?我的问题是如何验证登录代码…你找到了编写此代码的方法吗?我正好有这种情况。我会澄清我的问题,但我正在寻找验证c#中的登录所需的特定代码。@Jeffrey我知道在我们的SecureBackbox for.NET中是如何完成的,但不知道纯.NET框架是如何完成的。可能有更好的方法是查看类。文档示例显示了在运行过程中检查每个元素的代码。@HelloWorld如果我今天写这篇文章,我只会使用
if(errors?.Length>0)
:)C#6。很高兴知道;我没有深入研究ToArray()实现,以了解如果
Select()
IEnumerable
没有返回任何结果会发生什么。@ChrisBenard是检查证书是否与已知根目录匹配的代码真的可以吗?这段代码应该匹配这样的操作,并且几乎总是返回true:
chain.ChainElements.Cast().All(x=>x.Certificate.Thumbprint!=“XX”)
@MattiasNordqvist如果证书正常(未过期/吊销等),则由于使用了
X509VerificationFlags.AllowUnknownCertificateAuthority
,该证书将为真。稍后的指纹检查是必要的,以检查您在与
ExtraStore.Add()
的链中放置的权限。我有根证书和中间证书(由根签名),需要验证由中间签名的客户端证书。在这种情况下,我是否需要在ExtraStore中添加根和中间层,并需要使用哪个证书检查指纹?@Varsh听起来您确实需要添加根和中间层,并检查根的指纹。