C# X509Certificate 构造函数异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9951729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 11:21:52  来源:igfitidea点击:

X509Certificate Constructor Exception

c#.netx509certificate

提问by lukiffer

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

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

When loading a certificate from our database, on our staging server (Windows 2008 R2/IIS7.5) we get this exception:

当从我们的数据库加载证书时,在我们的临时服务器(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)

NOTE:This issue does not happen locally (Windows 7/Casini).

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

Any insight is greatly appreciated.

任何见解都非常感谢。

采纳答案by lukiffer

Turns out there's a setting in the IIS Application Pool configuration (Application Pools > Advanced Settings) to load the user profile for the application pool identity user. When set to false, the key containers aren't accessible.

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

So just set Load User Profileoption as True

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

App Pool->Advanced Settings Screen

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

回答by Chris Benard

More than likely, when you are running from Visual Studio/Cassini, it is accessing your usercertificate store, even though you're loading it from bytes. Could you please try this and see if it solves your issue:

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

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

This will cause IIS (which runs as the ASP.NET user which likely doesn't have access to a user store) to use the Machine store.

这将导致 IIS(以 ASP.NET 用户身份运行,可能无法访问用户存储)使用 Machine 存储。

This pageexplains the constructor in more detail, and this pageexplains the X509KeyStorageFlagsenumeration.

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

Edit:Based on the second linkfrom cyphr, it looks like it might be a good idea (if the previous solution doesn't work), to combine some of the FlagsAttributeenumeration values like so:

编辑:基于来自cyphr第二个链接,看起来它可能是一个好主意(如果以前的解决方案不起作用),将一些枚举值组合起来,如下所示:FlagsAttribute

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

Additionally, if you have access, you may want to try changing your Application Pool setting to use LocalService (and then restart the AppPool). This may elevate your permissions to an appropriate level if that is the problem.

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

Finally, you can use File.WriteAllBytesto write out the CertificatePKCS12contents to a pfx file and see if you can manually import it using the certificate console under MMC (you can delete after successful import; this is just to test). It could be that your data is getting munged, or the password is incorrect.

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

回答by Oleg

To be able really solve your problem and not just guess, what can it be, one need be able to reproduce your problem. If you can't provide test PFX file which have the same problem you have to examine the problem yourself. The first important question is: are the origin of the exception "An internal error occurred" in the private key part of the PKCS12 or in the public part of the certificate itself?

为了能够真正解决您的问题,而不仅仅是猜测,它可能是什么,需要能够重现您的问题。如果您不能提供具有相同问题的测试 PFX 文件,您必须自己检查问题。第一个重要问题是:异常“发生内部错误”的来源是PKCS12的私钥部分还是证书本身的公共部分?

So I would recommend you to try to repeat the same experiment with the same certificate, exported without private key(like .CER file):

因此,我建议您尝试使用相同的证书重复相同的实验,导出没有私钥(如 .CER 文件):

var certificate = new X509Certificate(cert.CertificateCER);

or

或者

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

It could help to verify whether the origin of your problem is the private keyor some properties of the certificate.

它可以帮助验证问题的根源是私钥还是证书的某些属性。

If you will have problem with the CER file you can safe post the link to the file because it have public information only. Alternatively you can at least execute

如果您对 CER 文件有疑问,您可以安全地发布该文件的链接,因为它只有公开信息。或者你至少可以执行

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

or

或者

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

(you can use some other options too) and post some partsof the output (for example properties of the private key without the PRIVATEKEYBLOB itself).

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

回答by Francisco

Use this code:

使用此代码:

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

回答by PanRycho

You need to import a .cer certificate to your local machine keystore. There's no need to import your .p12 cert - instead use the second certyficate issued to your account by Apple. I think it must be a valid pair of certificates (one in filesystem, second in keystore). You'll have to set all 3 flags in dll of course.

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

回答by David d C e Freitas

An alternative to changing the Load User Profile is to make the Application Pool use the Network ServiceIdentity.

更改负载用户配置文件的替代方法是使应用程序池使用网络服务标识。

See also What exactly happens when I set LoadUserProfile of IIS pool?

另请参阅设置 IIS 池的 LoadUserProfile 时究竟会发生什么?

回答by Michael Balloni

I had trouble on Windows 2012 Server R2 where my application could not load certificates for a PFX on disk. Things would work fine running my app as admin, and the exception said Access Denied so it had to be a permissions issue. I tried some of the above advice, but I still had the problem. I found that specifying the following flags as the third parameter of the cert constructor did the trick for me:

我在 Windows 2012 Server R2 上遇到了问题,我的应用程序无法为磁盘上的 PFX 加载证书。以管理员身份运行我的应用程序时一切正常,异常表示访问被拒绝,因此必须是权限问题。我尝试了上面的一些建议,但我仍然遇到了问题。我发现将以下标志指定为 cert 构造函数的第三个参数对我有用:

 X509KeyStorageFlags.UserKeySet | 
 X509KeyStorageFlags.PersistKeySet | 
 X509KeyStorageFlags.Exportable

回答by Thabiso Mofokeng

On an application running IIS 10, I managed to fix the access denied error by using LocalSystem identity for the app pool with the following code:

在运行 IIS 10 的应用程序上,我通过使用以下代码的应用程序池的 LocalSystem 标识设法修复了访问被拒绝错误:

new X509Certificate2(certificateBinaryData, "password"
                               , X509KeyStorageFlags.MachineKeySet |
                                 X509KeyStorageFlags.PersistKeySet);

Enabling Load User Profile didn't work for me and while there where many suggestions to do this, they did not indicate that setting for 'Load User Profile' to True only works on user accounts and not:

启用加载用户配置文件对我不起作用,虽然有很多建议可以执行此操作,但他们并未指出将“加载用户配置文件”设置为 True 仅适用于用户帐户,而不适用于:

  1. ApplicationPoolIdentity
  2. NetworkService
  1. 应用程序池标识
  2. 网络服务