为什么在使用IIS时会收到Cryptography_CSP_NoPrivateKey,而在使用VS开发服务器时却没有?

时间:2009-03-25 15:00:00

标签: c# web-services security certificate signing

我正在使用外部Web服务的Web应用程序。此外部Web服务要求我签署我的每个请求。所以我使用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更改私钥权限,以便Everyone拥有对它的完全访问权限。你可以从这里看到这个:

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

如果你可以帮助我,我一定会很感激。我已经花了好几个小时,如果我犯了一个你们可以看到的根本错误,我不想花更多的时间。顺便说一句:我正在Windows Server 2008上使用Visual Studio 2008进行开发,关闭UAC: - )

真的很期待你们的回复。感谢。

1 个答案:

答案 0 :(得分:2)

: - )

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

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

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

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

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

  

C:\ MyTools> FindPrivateKey.exe My 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 My 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 My LocalMachine -t“8c 1a e6 1b 7d f1 f8 18 c8 26 b6 fa cd 60 fd 94 c7 a1 96 58”
  私钥目录:
  的 C:\ ProgramData \微软\加密\ RSA \ MachineKeys的
  私钥文件名:
  b3765d4d5a902371ea91c5c9a521932e_96ce3a90-5634-44e6-8aa2-acbaccb8b3bf

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

现在有效!!!

我真的不能感谢你的博客Tim。谢谢。