在.Net中创建并验证x509证书

时间:2013-02-13 22:00:43

标签: c# .net certificate x509certificate2

关于我的企业项目(仅限内联网),我遇到了使用.net System.Security.Cryptography.X509Certificates验证证书的问题

第1步:创建根证书

使用makecert创建根证书并将其安装到受信任的根证书颁发机构

makecert -r -pe -n "CN=Test Labs (CA)" -ss CA -sr CurrentUser -a sha256 -cy authority -sky signature -sv TestLabCA.pvk TestLabCA.cer
pvk2pfx -pvk TestLabCA.pvk -spc TestLabCA.cer -pfx TestLabCA.pfx

第2步:创建证书并使用根证书进行签名

使用makecert创建证书,使用根证书对其进行签名,然后将其安装到受信任的发布者

makecert -pe -n "CN=Test Labs (SPC)" -a sha256 -cy end -sky signature -ic TestLabCA.cer -iv TestLabCA.pvk -sv TestLabSPC.pvk TestLabSPC.cer
pvk2pfx -pvk TestLabSPC.pvk -spc TestLabSPC.cer -pfx TestLabSPC.pfx

第3步:在代码中验证

这是验证证书的C#代码示例:

X509Certificate2 rootCertificate = new X509Certificate2("TestLabCA.cer");
X509Certificate2 certificate = new X509Certificate2("TestLabSPC.cer");

// will return true
Console.WriteLine("{0}, verified = {1}", rootCertificate.GetName(), rootCertificate.Verify());

// will return false
Console.WriteLine("{0}, verified = {1}", certificate.GetName(), certificate.Verify());

// validate the chain
var chain = new X509Chain();
chain.Build(certificate);
Console.WriteLine("{0}, verified root of chain = {1}", certificate.GetName(), chain.ChainElements[chain.ChainElements.Count-1].Certificate.Verify());

问题:

如果我想验证证书,我是否必须检查链并验证链中的最后一个,假设这是根证书?

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

你必须创建一个信任链,是的。这意味着您必须将其追溯到您信任的证书。这不一定是根证书,但通常信任根证书而不是中间证书。有时您只希望允许单个实体使用单个证书。只要您确定它是正确的证书,您就可以简单地信任单叶证书,因此“链”将包含单个证书。一个例子是自签名的根证书,有时由Web服务使用。

请注意,证书链的验证只是证书总验证的一部分。您需要确保证书尚未被撤销,证书仍然有效(在生效日期和到期日期之间)。有时,还有用于验证证书的附加专有规则,例如:在DB中存在证书ID - 白名单/黑名单。

答案 1 :(得分:2)

除了Maarten Bodewes的回答:

要轻松验证链是否有效,您可以使用以下代码:

X509Certificate2 Certificate = new X509Certificate2( "Certificate.pfx" );
X509Chain CertificateChain = new X509Chain();
//If you do not provide revokation information, use the following line.
CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
bool IsCertificateChainValid = CertificateChain.Build( Certificate );

当证书链正确时,IsCertificateChainValid返回true。 如果它返回false,你可以使用

CertificateChain.ChainStatus

有关为何状态无效的信息。 可能的值包括NotTimeValid,UntrustedRoot。