我们已经创建了一个自签名CA证书,我们用它来签署其他证书以用于SSL。这些证书将安装在我们无法访问的其他服务器中,并且将严格与其他客户端(如移动应用程序)进行通信。
当这些客户端(用.NET编写)使用HTTPS向服务器发出请求时,我们会收到“从服务器收到的证书无效”错误,因为CA证书不是该客户端上的可信CA.
我们希望使用ServicePointManager.ServerCertificateValidationCallback
绕过此安全性,但前提是所使用的证书是由我们的CA证书签署的。
我可以查看certificate.Issuer
,但这很容易被任何人欺骗。如何获取无效证书的颁发者证书的指纹或公钥?如果我可以访问它,我可以很容易地将它与我认为有效的那个进行比较,并忽略证书错误并继续请求。
更新
我想我越来越近了。看起来我们要做的事情是不可行的,所以方向略有不同。
使用X509Chain
,我们可以使用以下代码验证证书是否为CA的子级:
var caCert = new X509Certificate2(@"[path]\MyCA.cer");
var newChain = new X509Chain();
newChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
newChain.ChainPolicy.ExtraStore.Add(caCert);
var res = newChain.Build(certInQuestion);
Build()
仍然返回false(正如预期的那样,因为客户端上不信任CA),但现在newChain.ChainStatus[0].Status
正在返回UntrustedRoot
。根据我的测试,这意味着链被验证,因为如果我提供不同的CA证书,它将失败InvalidChain
。
总之,这告诉我,如果状态为UntrustedRoot
,则证书是使用我们的CA证书创建的,因此它是有效的,其他任何东西都是假的!
我的假设是否正确?
答案 0 :(得分:0)
我不完全确定这是你正在寻找的东西,但它可能会把你推向正确的方向。这是我用来查找我刚创建并使用MAKECERT.EXE&提取的证书的PowerShell脚本。 CERTMGR.EXE:
# get certificate thumbprint
$appCertificate = Get-PfxCertificate -FilePath $certificateFullPath
Write-Host " .. adding certificate to local machine root" -ForegroundColor Gray
& $ExeCertManager /add $certificateFullPath /s /r localMachine root
Write-Host " Certificate installed on local machine" -ForegroundColor Gray
Write-Host " .. exporting private key for certificate" -ForegroundColor Gray
Get-ChildItem cert:\\localmachine\my | Where-Object {$_.Thumbprint -eq $appCertificate.Thumbprint} | ForEach-Object {
$CertPfxName = (Get-Item -Path $certificateFullPath).BaseName
}
答案 1 :(得分:0)
这是错误的解决方案。您应该将自签名证书作为受信任的CA证书安装在所有客户端中,或者更好的方法是将其从已受信任的CA签名。不要为此编写代码。
答案 2 :(得分:0)
根据这个答案,可能的解决方案似乎是您可以通过电子邮件发送证书:https://stackoverflow.com/a/4473799/674700。
答案 3 :(得分:0)
以下是一些信息链接和一些生成免费公钥和私钥的工具:
https://www.igolder.com/pgp/generate-key/
我认为EJP的解决方案是最可接受的。 @EJP,你能给我们一些应用程序的例子,它们可以帮助我们成为一个小小的CA"。