Keyset does not exist /r /n

645 views Asked by At

I was tasked to create a integration service between our SharePoint app and one service provider. One requirement of the service provider I'm going to integrate with is to provide them a public key which they will use to verify my request which was signed using our own private key.

Initially I created a console app which reads the certificate store and gets the private key which to use to sign my request and all. The console app works fine so I decided to move it now within our SharePoint application. Unfortunately it fails in this specific part of the code:

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

The whole code snippet which gets the certificate and does the signing can be found below:

        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]

I tried following the steps in this link. I first uninstalled my existing private key in the server. I then imported it back to the Certificate store and confirmed that there was a Thumbprint property. After that, I ran findprivatekey.exe and was able to navigate to the MachineKeys folder. From there I added different users ranging from Network Services, IIS_IUSRS and even local accounts I used to login to the server as well as SPFarm admin but I still keep getting the error.

I also made sure that the key I added was exportable so there should be a way for it the application to extract the private key attached to the certificate.

[UPDATE 2]

I updated the code so that it just returns one certificate prior to assigning it to the variable I was using to extract the private key. Still the same issue even if I can see that the certs variable is returning exactly one record.

1

There are 1 answers

1
lem.mallari On BEST ANSWER

After much checking I realized I missed one important part in calling the method code block above. I forgot to wrap it an elevate privilege block. After doing that, the code functioned similarly as my console app.

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);

    ...
});