C# X509 证书未在服务器上加载私钥文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14263457/
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-10 11:14:44  来源:igfitidea点击:

X509 certificate not loading private key file on server

c#asp.net-mvc-3google-analytics-apix509certificate2

提问by acurcie

I'm using the Google Analytics API and I followed this SO question to set up the OAuth: https://stackoverflow.com/a/13013265/1299363

我正在使用 Google Analytics API,我按照这个 SO 问题来设置 OAuth:https: //stackoverflow.com/a/13013265/1299363

Here is my OAuth code:

这是我的 OAuth 代码:

public void SetupOAuth ()
{
    var Cert = new X509Certificate2(
        PrivateKeyPath, 
        "notasecret", 
        X509KeyStorageFlags.Exportable);
    var Provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, Cert)
    {
        ServiceAccountId = ServiceAccountUser,
        Scope = ApiUrl + "analytics.readonly"
    };
    var Auth = new OAuth2Authenticator<AssertionFlowClient>(Provider, AssertionFlowClient.GetState);
    Service = new AnalyticsService(Auth);
}

PrivateKeyPath is the path of the private key file provided by Google API Console. This works perfectly on my local machine, but when I push it up to our test server I get

PrivateKeyPath 是 Google API Console 提供的私钥文件的路径。这在我的本地机器上完美运行,但是当我将它推送到我们的测试服务器时,我得到了

System.Security.Cryptography.CryptographicException: An internal error occurred.

with the following stack trace (irrelevant parts removed):

使用以下堆栈跟踪(删除了不相关的部分):

System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +33
System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0
System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) +237
System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) +140
Metrics.APIs.GoogleAnalytics.SetupOAuth() in <removed>\Metrics\APIs\GoogleAnalytics.cs:36
Metrics.APIs.GoogleAnalytics..ctor(String PrivateKeyPath) in <removed>\Metrics\APIs\GoogleAnalytics.cs:31

So it appears as if it is having trouble loading the file. I've checked the PrivateKeyPath that is passed in and it is pointing to the correct location.

所以看起来好像在加载文件时遇到了问题。我检查了传入的 PrivateKeyPath 并且它指向正确的位置。

Any ideas? I don't know if this is an issue with the server, the file, the code or what.

有任何想法吗?我不知道这是服务器、文件、代码还是什么的问题。

采纳答案by Wiktor Zychla

One of things that comes to my mind is the identity of your app pool, make sure that the Load user profileis turned on otherwise the crypto subsystem does not work.

我想到的一件事是您的应用程序池的身份,请确保加载用户配置文件已打开,否则加密子系统将无法工作。

回答by Simon_Weaver

I'm loading my p12file with

我正在加载我的p12文件

new X509Certificate2(
HostingEnvironment.MapPath(@"~/App_Data/GoogleAnalytics-privatekey.p12"), ....

I actually got a FileNotFoundException even though File.Exists(filename)returned true.

即使File.Exists(filename)返回 true,我实际上也得到了 FileNotFoundException 。

As @Wiktor Zychla said it's as simple as enabling Load User Profile

正如@Wiktor Zychla 所说,这就像启用一样简单 Load User Profile

Here's an image of the setting that needs changing

这是需要更改的设置的图像

Just right click on the app pool under 'Application Pools' in IIS and select 'Advanced Settings' and the setting you need is about halfway down.

只需在 IIS 中“应用程序池”下的应用程序池上单击鼠标右键,然后选择“高级设置”,您需要的设置就在一半左右。

enter image description here

在此处输入图片说明

Tip: I'd recommend commenting your code with this to prevent future time wasted since it's so obscure if you've never come across it before.

提示:我建议您用它来注释您的代码,以防止将来浪费时间,因为如果您以前从未遇到过它,它是如此晦涩难懂。

  // If this gives FileNotFoundException see 
  // http://stackoverflow.com/questions/14263457/

回答by WhoAmI

Nope, is "File.Exists(...)" also in advanced settings? I had 3 pools, all of them had true enabled for "Load User Profile". I'm thinking my problem might have something to do with dependencies and NuGet Packages as the code worked just fine as a Console App but gives me problem in MVC.

不,“File.Exists(...)”也在高级设置中吗?我有 3 个池,它们都为“加载用户配置文件”启用了真正的功能。我认为我的问题可能与依赖项和 NuGet 包有关,因为代码作为控制台应用程序工作得很好,但在 MVC 中给了我问题。

回答by VahidN

Also try specifying X509KeyStorageFlags

也尝试指定 X509KeyStorageFlags

    var certificate = new X509Certificate2(KeyFilePath, KeyFilePassword, 
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | 
X509KeyStorageFlags.Exportable);

回答by Shani

As mentioned above you need to configure IIS but as our case, some time you need to check the permission of the following folder:

如上所述,您需要配置 IIS,但就我们而言,有时您需要检查以下文件夹的权限:

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

If you set X509KeyStorageFlagsparameter it will create a key file in this folder. In my case there was a difference in permission of this folder. Pool account was not added in the mentioned folder.

如果您设置X509KeyStorageFlags参数,它将在此文件夹中创建一个密钥文件。就我而言,此文件夹的权限有所不同。未在提到的文件夹中添加池帐户。