【问题标题】:Why do I get Cryptography_CSP_NoPrivateKey when using IIS but not when using VS development server?为什么我在使用 IIS 时得到 Cryptography_CSP_NoPrivateKey 而在使用 VS 开发服务器时却没有?
【发布时间】:2010-10-15 11:36:02
【问题描述】:

我正在做一个利用外部网络服务的网络应用程序。这个外部网络服务要求我签署我的每一个请求。所以我使用WebServicesClientProtocol 类和.NET 2.0,首先使用外部Web 服务,然后手动编辑Reference.cs 文件并将扩展类从System.Web.Services.Protocols.SoapHttpClientProtocol 更改为Microsoft.Web.Services2.WebServicesClientProtocol。然后在Page_Load 方法中我有以下代码:

try
{
    // Create the ws endpoint
    var uriServiceAddress = new Uri("urn:something-wse:something_NNNN");
    var uribuilderViaRouter = new UriBuilder("http://xx.xxx.xx/SrvXXX_NNNN/Test.asmx");
    var endpointReference = new EndpointReference(uriServiceAddress, uribuilderViaRouter.Uri);

    // Create the ws client
    var client = (WebServicesClientProtocol) new Test.Something();
    client.Destination = endpointReference;

    // Read the certificate from MyStore on LocalMachine
    X509CertificateStore localStore = X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
    X509SecurityToken securityToken = null;
    if (!localStore.OpenRead()) throw new Exception("Unable to open localstore for read");
    X509CertificateCollection certificateCollection = localStore.FindCertificateBySubjectString("email@subject.test");
    if (certificateCollection.Count == 0) throw new Exception("Unable to obtain security token.");
    securityToken = new X509SecurityToken(certificateCollection[0]);
    localStore.Close();

    // Attach the security toekn to the client request
    client.RequestSoapContext.Security.Tokens.Add(securityToken);
    client.RequestSoapContext.Security.Elements.Add(new MessageSignature(securityToken));

    // Set the timeouts
    client.RequestSoapContext.Security.Timestamp.TtlInSeconds = 2 * 60;
    client.Timeout = 60 * 10 * 1000;    // 10 mínútur ættu að duga í flest.

    // Call the test function
    DataSet set = ((Test.Something)client).searchMethod("Parameter 1", "Parameter 2");
    Label1.Text = User.Identity.Name+ " worked! " + set.Tables.Count + " tables!";
}
catch (Exception exc)
{
    Label1.Text = User.Identity.Name + " exception: " + exc.ToString();
}

当我使用 Visual Studio 开发服务器运行它时,它工作正常,但是当我更改为 IIS 时它停止工作,并且我得到了丑陋的 Cryptography_CSP_NoPrivateKey 异常。

1) 我已经使用 MMC 将证书正确读入 LocalMachine/MyStore,然后我使用 WSE 2.0 SP3 更改了私钥权限,以便每个人都可以完全访问它。你可以从这里看到:

alt text http://www1.ruedenet.is/files/CertError1.png

2) 我还设置了属性,以便在调试应用程序时使用 Visual Studio 开发服务器:

alt text http://www1.ruedenet.is/files/CertError2.png

3) 然后我运行它并得到一个不错的结果:

alt text http://www1.ruedenet.is/files/CertError3.png

4) 但是,当我将属性更改为使用 IIS(并让 VS 创建虚拟目录)时,如下所示:

alt text http://www1.ruedenet.is/files/CertError4.png

5) 我还更改了 IIS 中的身份验证方法,以便我能够登录(真的没有理由):

alt text http://www1.ruedenet.is/files/CertError5.png

6) 所以我被要求登录 Windows:

alt text http://www1.ruedenet.is/files/CertError6.png

7) 然后我的页面运行并产生错误:

alt text http://www1.ruedenet.is/files/CertError7.png

如果您能帮我解决这个问题,我将不胜感激。我已经在这上面花了几个小时,如果我犯了你们可以看到的基本错误,我不想花更多时间。顺便说一句:我在关闭 UAC 的情况下在 Windows Server 2008 上使用 Visual Studio 2008 进行开发:-)

真的很期待收到你们的来信。谢谢。

【问题讨论】:

    标签: c# web-services security certificate signing


    【解决方案1】:

    :-)

    我已经通过几个步骤解决了这个问题:

    1) 我将Default Application Pool 的用户更改为我的用户名...

    alt text http://www1.ruedenet.is/files/ErrorFix1.png

    ...这很有效。我将应用程序池的用户改回NETWORK SERVICE,但它不再起作用。这告诉我问题与NETWORK SERVICE 用户有关。所以我回去寻找这个用户的权限可能是什么问题。

    2) 在浏览和阅读网页时,我在 http://timjacobs.blogspot.com/2008/11/app-v-45-certificate-galore.html 找到了 Tim Jacobs 的博文 App-V 4.5 Certificate Galore。好吧,直到最后他谈到了私钥在磁盘上的存储位置,这里面并没有什么新东西。所以我运行了FindPrivateKey.exe 工具,...

    C:\MyTools>FindPrivateKey.exe 我的 LocalMachine -t "8c 1a e6 1b 6d f2 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
    私钥目录:
    C:\Users\alfred\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-3612370315-2559787 071-3412320394-1135
    私钥文件名:
    b3765d4123902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acb123b8b3bf

    ...告诉我私钥的位置在C:\Users\alfred\... 目录中,而NETWORK SERVICE 用户可能无权访问该目录!!!

    3) 因此,我按照 Tim 的建议使用 MMC 从 Local Computer/Personal/Certificates 导出证书和私钥,然后将其导入 Local Computer/Trusted Root Certificate Authorities/Certificates。导出后,FindPrivateKey.exe 报告,...

    C:\MyTools>FindPrivateKey.exe 我的 LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
    FindPrivateKey 失败的原因如下:在商店中找不到密钥为“8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58”的证书。

    ... 这告诉我导出成功了。导入并复制粘贴回Local Computer/Personal/Certificates 后,我得到...

    C:\MyTools>FindPrivateKey.exe 我的 LocalMachine -t "8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58"
    私钥目录:
    C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
    私钥文件名:
    b3765d4d5a902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acbaccb8b3bf

    ...现在私钥在公共位置,C:\ProgramData\... 目录。然后,我使用 X509 证书工具NETWORK SERVICE 用户的私钥权限更改为 完全访问,就像我之前所做的那样。

    现在可以了!!!

    对于您的博文蒂姆,我非常感谢。谢谢。

    【讨论】:

      猜你喜欢
      • 2016-08-02
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多