键集不存在 /r /n

Keyset does not exist /r /n

我的任务是在我们的 SharePoint 应用程序和一个服务提供商之间创建集成服务。我要集成的服务提供商的一项要求是向他们提供一个 public 密钥,他们将使用该密钥来验证我的请求,该请求是使用我们自己的私钥签名的。

最初我创建了一个控制台应用程序,它读取证书存储并获取用于签署我的请求和所有请求的私钥。控制台应用程序运行良好,因此我决定现在将其移动到我们的 SharePoint 应用程序中。不幸的是,它在代码的这个特定部分失败了:

key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));

获取证书并进行签名的完整代码片段如下:

        X509Certificate2 privateCert = null;
        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        store.Open(OpenFlags.MaxAllowed);

        var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "thumbprinthere", true);

        if (certs.Count > 0)
        {
            privateCert = certs[0];
        }

        RSACryptoServiceProvider key = new RSACryptoServiceProvider();
        key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));

        byte[] sig = key.SignData(Encoding.ASCII.GetBytes(data), CryptoConfig.MapNameToOID("SHA256"));
        string signature = Convert.ToBase64String(sig);

[更新]

我尝试按照 link 中的步骤操作。我首先卸载了服务器中现有的私钥。然后我将它导入回证书存储并确认有一个指纹 属性。在那之后,我 运行 findprivatekey.exe 并且能够导航到 MachineKeys 文件夹。从那里我添加了不同的用户 运行ging 来自网络服务,IIS_IUSRS 甚至我用来登录服务器的本地帐户以及 SPFarm 管理员,但我仍然不断收到错误。

我还确保我添加的密钥是可导出的,因此应用程序应该有一种方法可以提取附加到证书的私钥。

[更新 2]

我更新了代码,以便它在将它分配给我用来提取私钥的变量之前只 returns 一个证书。即使我看到 certs 变量正好返回一条记录,问题仍然存在。

经过多次检查,我意识到我在调用上面的方法代码块时遗漏了一个重要部分。我忘了把它包装成一个提升权限块。这样做之后,代码的功能与我的控制台应用程序类似。

SPSecurity.RunWithElevatedPrivileges(delegate())
{
    ...

    X509Certificate2 privateCert = null;
    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.MaxAllowed);

    var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "<thumbprinthere>", true);

    if (certs.Count > 0)
    {
        privateCert = certs[0];
    }

    RSACryptoServiceProvider key = new RSACryptoServiceProvider();
    key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));

    byte[] sig = key.SignData(Encoding.ASCII.GetBytes(data), CryptoConfig.MapNameToOID("SHA256"));
    string signature = Convert.ToBase64String(sig);

    ...
});