我正在尝试以编程方式使用证书,而不是使用商店。我正在使用文件名和密码创建X509Certificate2
。
当我手动将根证书添加到受信任人员中的证书存储区时,此工作正常。但是,我宁愿不必在每次部署时都这样做 - 我宁愿以编程方式处理它。
当我从证书存储中删除根证书时,我得到一个例外。
我读过的所有内容似乎都说我必须手动将根证书添加到证书存储区,否则信任链将无效。
问题:是否有编程方式来设置信任链,所以我不必手动完成?
代码如下:
var serverCert = new X509Certificate2("FullPathToMyCertificate.cer", "Password");
Client.ClientCredentials.ServiceCertificate.DefaultCertificate = serverCert;
我尝试使用客户端时发生的异常是:
System.IdentityModel.Tokens.SecurityTokenValidationException
The X.509 certificate CN=notrealcertname, OU=TPA, OU=BMP, OU=Projects, O=Somebody, C=US is not in the trusted people store.
The X.509 certificate CN=notrealcertname, OU=TPA, OU=BMP, OU=Projects, O=Somebody, C=US chain building failed.
The certificate that was used has a trust chain that cannot be verified.
Replace the certificate or change the certificateValidationMode.
A certificate chain could not be built to a trusted root authority.
答案 0 :(得分:4)
默认情况下,使用过的组件会验证链 - 当无法验证链时,您会获得该异常。
如果您想要执行所有操作,包括在代码中验证链,那么您需要implement "custom validation" and integrate that into the WCF Host:
Client.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.Custom;
Client.ServiceCertificate.Authentication.CustomCertificateValidator =
new MyCertificateValidator();
另一种选择是完全禁用验证(非生产!!! )
Client.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.None;
编辑 - 评论后:
为了自己验证链条,您应该查看X509Chain和X509Store - 了解如何实施此类链验证,请查看Mono's implementation { {1}} ...基本上您使用Verify
方法在X509Certificate2Collection上搜索父级,依此类推......具有自定义验证的验证条件取决于您(有效签名,未过期) ...)。
MSDN上的一些参考链接: