存储在证书存储区中的证书随着时间的推移从ASP.NET应用程序中消失
我从Thawte获得了一个代码签名证书,用于动态生成并签署ClickOnce部署清单。问题是,当我们重新启动IIS或重新导入签名证书生成和体征,这些体现在ASP.NET应用程序工作正常,但随着时间的推移以下功能无法找到该证书:存储在证书存储区中的证书随着时间的推移从ASP.NET应用程序中消失
private static X509Certificate2 GetSigningCertificate(string thumbprint)
{
X509Store x509Store = new X509Store(StoreLocation.CurrentUser);
try
{
x509Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection x509Certificate2Collection = x509Store.Certificates.Find(
X509FindType.FindByThumbprint, thumbprint, false);
if (x509Certificate2Collection.Count == 0)
throw new ApplicationException(
"SigningThumbprint returned 0 results. Does the code signing certificate exist in the personal store?",
null);
if (x509Certificate2Collection.Count > 1)
throw new ApplicationException(
"SigningThumbprint returned more than 1 result. This isn't possible", null);
var retval = x509Certificate2Collection[0];
if(retval.PrivateKey.GetType() != typeof(RSACryptoServiceProvider))
throw new ApplicationException("Only RSA certificates are allowed for code signing");
return retval;
}
finally
{
x509Store.Close();
}
}
最终,应用程序开始抛出无法找到证书的错误。我很难过,因为我认为证书安装正确(或者大部分是正确的),因为它在我们启动ASP.NET应用程序时确实找到了证书,但是在某些时候我们击中了Count == 0分支,而这不正确:该证书位于应用程序池用户的“当前用户\个人”证书存储区中。
问题:为什么突然出现的证书“消失”或无法找到?
我们自己(痛苦地)找出它。
证书需要安装在LocalMachine存储中,并且应用程序池帐户使用WinHttpCertCfg或CACLS.exe读取证书的权限(如果要从ASP.NET应用程序使用该证书)。使用运行应用程序池的帐户的CurrentUser存储引起了问题。我在猜测存在某种竞争条件,或者对于未在交互式登录会话中运行的用户访问CurrentUser存储区并不完全酷。
起初我们无法做到这一点,因为我们调用MAGE工具来执行ClickOnce部署清单创建/签名,并且需要将代码签名证书放在CurrentUser \ My商店中。然而,我们已经通过a)从模板文件创建清单并替换我们需要替换的值以及b)通过经由BuildTasks中存在的反射调用代码MAGE调用来签署清单,从而消除了对MAGE的需求。 v3.5 DLL。因此,我们可以更多地控制我们用来签署清单的证书,并且可以将其放在任何我们想要的地方。否则,如果我们没有稍微“降低水平”,我们会被卡住。