X509Certificate构造函数异常

luk*_*fer 68 .net c# x509certificate

//cert is an EF Entity and 
//    cert.CertificatePKCS12 is a byte[] with the certificate.

var certificate = new X509Certificate(cert.CertificatePKCS12, "SomePassword");
Run Code Online (Sandbox Code Playgroud)

从我们的数据库加载证书时,在我们的登台服务器(Windows 2008 R2/IIS7.5)上,我们遇到以下异常:

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)
Run Code Online (Sandbox Code Playgroud)

注意:此问题不会在本地发生(Windows 7/Casini).

非常感谢任何见解.

luk*_*fer 118

原来在IIS应用程序池配置(应用程序池>高级设置)中有一个设置来加载应用程序池标识用户的用户配置文件.设置为false时,无法访问密钥容器.

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

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

  • 我试图在Azure上执行此操作,但我不知道我可以更改"加载用户配置文件"选项.任何建议......我对证书世界还很新... (2认同)
  • @DanB for Azure 添加应用程序设置:WEBSITE_LOAD_USER_PROFILE=1 (2认同)
  • 我不知道你是谁,但是谢谢!!!!现在是凌晨 3:40,剩下的事情你就可以想象了…… (2认同)

Chr*_*ard 57

很可能,当您从Visual Studio/Cassini运行时,它正在访问您的用户证书存储区,即使您是从字节加载它.你可以尝试一下,看看它是否解决了你的问题:

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword", X509KeyStorageFlags.MachineKeySet);
Run Code Online (Sandbox Code Playgroud)

这将导致IIS(作为ASP.NET用户运行,可能无法访问用户存储)使用计算机存储.

此页面更详细地解释了构造函数,此页面解释了X509KeyStorageFlags枚举.

编辑: 基于对第二链路cyphr,它看起来像它可能是一个好主意(如果前面的解决方案不工作),对一些结合起来FlagsAttribute,像这样枚举值:

var certificate = new X509Certificate(
    cert.CertificatePKCS12, "SomePassword",
    X509KeyStorageFlags.MachineKeySet
    | X509KeyStorageFlags.PersistKeySet
    | X509KeyStorageFlags.Exportable);
Run Code Online (Sandbox Code Playgroud)

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

最后,您可以使用File.WriteAllBytesCertificatePKCS12内容写出到pfx文件,看看是否可以使用MMC下的证书控制台手动导入它(您可以在成功导入后删除;这只是为了测试).可能是您的数据被窃取,或者密码不正确.


小智 29

使用此代码:

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


Mic*_*oni 7

我在Windows 2012 Server R2上遇到了问题,我的应用程序无法为磁盘上的PFX加载证书.事情可以很好地运行我的应用程序作为管理员,并且异常说Access拒绝所以它必须是权限问题.我尝试了一些上述建议,但我仍然遇到了问题.我发现指定以下标志作为cert构造函数的第三个参数对我有用:

 X509KeyStorageFlags.UserKeySet | 
 X509KeyStorageFlags.PersistKeySet | 
 X509KeyStorageFlags.Exportable
Run Code Online (Sandbox Code Playgroud)