我的任务是在SharePoint应用和一个服务提供商之间创建集成服务。我要与之集成的服务提供商的一个要求是为他们提供一个公钥,用于验证我使用我们自己的私钥签名的请求。
最初我创建了一个控制台应用程序,它读取证书存储区并获取用于签署我的请求的私钥。控制台应用程序工作正常,所以我决定现在在我们的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);
[UPDATE]
我尝试按照此link中的步骤操作。我首先卸载了服务器中现有的私钥。然后我将其导回到证书存储区并确认存在Thumbprint属性。之后,我运行了findprivatekey.exe并能够导航到MachineKeys文件夹。从那里我添加了不同的用户,包括网络服务,IIS_IUSRS,甚至我用来登录服务器的本地帐户以及SPFarm管理员,但我仍然一直收到错误。
我还确保我添加的密钥是可导出的,因此应该有一种方法可以让应用程序提取附加到证书的私钥。
[更新2]
我更新了代码,以便在将其分配给我用于提取私钥的变量之前返回一个证书。即使我可以看到certs
变量只返回一条记录,仍然是同一个问题。
答案 0 :(得分:0)
经过多次检查后,我意识到我错过了调用上面方法代码块的一个重要部分。我忘了将它包装成一个提升特权块。完成后,代码的功能与我的控制台应用程序类似。
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);
...
});