X509Certificate构造函数exception

//cert is an EF Entity and // cert.CertificatePKCS12 is a byte[] with the certificate. var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword"); 

从我们的数据库加载证书时,在我们的登台服务器(Windows 2008 R2 / IIS7.5)上,我们得到这个exception:

 System.Security.Cryptography.CryptographicException: An internal error occurred. at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags) 

注意:这个问题不会发生在本地(Windows 7 / Casini)。

任何有识之士都非常感激。

原因是在IIS应用程序池configuration(应用程序池>高级设置)中有一个设置来加载应用程序池标识用户的用户configuration文件。 设置为false时,密钥容器不可访问。

所以只需将Load User Profile选项设置为True

应用程序池 - >高级设置屏幕

当您从Visual Studio / Cassini运行时,即使您正在从字节进行加载,它也会访问您的用户证书存储。 你可以试试这个,看看它是否能解决你的问题:

 var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet); 

这将导致IIS(作为可能无法访问用户存储的ASP.NET用户运行)使用Machine存储。

这个页面更详细地解释了构造函数, 这个页面解释了X509KeyStorageFlags枚举。

编辑:基于从cyphr的第二个链接 ,它看起来像是一个好主意(如果以前的解决scheme不起作用),结合一些FlagsAttribute枚举值,如下所示:

 var certificate = new X509Certificate( cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 

此外,如果您有权访问,则可能需要尝试将“应用程序池”设置更改为使用LocalService(然后重新启动AppPool)。 如果这是问题,这可能会将您的权限提升到适当的级别。

最后,您可以使用File.WriteAllBytesCertificatePKCS12内容写出到pfx文件中,并查看是否可以使用MMC下的证书控制台手动导入它(可以在成功导入后删除;这仅仅是testing)。 这可能是因为你的数据正在消失,或者密码不正确。

使用此代码:

 certificate = new X509Certificate2(System.IO.File.ReadAllBytes(p12File) , p12FilePassword , X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); 

我在Windows 2012 Server R2上遇到了麻烦,我的应用程序无法为磁盘上的PFX加载证书。 事情会正常运行我的应用程序作为pipe理,exception说拒绝访问,所以它必须是一个权限问题。 我尝试了一些上述build议,但是我仍然遇到了这个问题。 我发现指定下面的标志作为cert构造函数的第三个参数为我做了诡计:

  X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable 

为了能够真正解决你的问题,而不仅仅是猜测,有什么可以的,一个需要能够重现你的问题 。 如果您无法提供具有相同问题的testingPFX文件,则必须自行检查问题。 第一个重要的问题是:PKCS12的私钥部分或证书本身的公开部分是“内部错误发生”例外的起源?

所以我build议您尝试使用相同的证书重复相同的实验,导出时不使用私钥 (如.CER文件):

 var certificate = new X509Certificate(cert.CertificateCER); 

要么

 var certificate = new X509Certificate.CreateFromCertFile("My.cer"); 

这可能有助于validation问题的根源是私钥还是证书的某些属性。

如果CER文件出现问题,您可以安全地发布文件的链接,因为它只有公共信息。 或者,你至less可以执行

 CertUtil.exe -dump -v "My.cer" 

要么

 CertUtil.exe -dump -v -privatekey -p SomePassword "My.pfx" 

(也可以使用其他一些选项),并发布输出的某些部分 (例如,没有PRIVATEKEYOBOB本身的私钥的属性)。

更改加载用户configuration文件的替代方法是使应用程序池使用networking服务标识。

另请参见我设置IIS池的LoadUserProfile时发生了什么?

您需要将.cer证书导入本地计算机密钥库。 没有必要导入您的.p12证书 – 而是使用Apple发给您的帐户的第二个证书。 我认为它必须是一对有效的证书(一个在文件系统中,另一个在密钥库中)。 你必须在dll中设置所有3个标志。