Nicke Manarin
Nicke Manarin

Reputation: 3360

"Key not valid for use in specified state" while trying to Sign a Xml

My History:

I need to sign all my Xml's before uploading to the government agency. To sign, I'm using client certificates loaded from the X509Store:

var repo = new X509Store("My", StoreLocation.CurrentUser);

repo.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

foreach (X509Certificate2 certCurrent in repo.Certificates)
{
    if (!certCurrent.Subject.Equals(subject)) continue;

    if (certCurrent.NotAfter > DateTime.Now)
    {
        repo.Close();
        return certCurrent;
    }
}

repo.Close();
return null;

And SignedXml (XmlDocument xmlDoc, string id, X509Certificate2 certificate):

var refer = new Reference();
refer.Uri = "#" + id;
refer.AddTransform(new XmlDsigEnvelopedSignatureTransform());
refer.AddTransform(new XmlDsigC14NTransform());

var signedXml = new SignedXml(xmlDoc);
signedXml.SigningKey = certificate.PrivateKey;
signedXml.AddReference(refer);

signedXml.ComputeSignature();

var key = new KeyInfo();
key.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = key;

//Final signature xml block.
XmlElement signedBlock = signedXml.GetXml();

Problem:

One of my clients changed his PC password and out of nothing the second block of code throws this error:

Message - 
    Key not valid for use in specified state.
Type - 
    CryptographicException
Source - 
    mscorlib
TargetSite - 
    System.Security.Cryptography.SafeProvHandle CreateProvHandle(System.Security.Cryptography.CspParameters, Boolean)
StackTrace - 
    at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
    at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
    at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
    at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
    at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
    at Util.SignXml.Sign(XmlDocument xmlDoc, String id, X509Certificate2 certificate, String& error)

It says that the getter of the PrivateKey is throwing that exception. Later, I'll try to install that certificate again, with the Exportable checked.

PS: Windows Server 2003

Upvotes: 0

Views: 3443

Answers (2)

syed Fakhir
syed Fakhir

Reputation: 21

Creating a new test certificate seems to have solved the problem. This blog post pointed me in the right direction.

Open the properties page for the project that is giving the error. Click the Signing tab. Click Create Test Certificate. Enter a password and click OK. This got things working again for me.

Upvotes: 0

Nicke Manarin
Nicke Manarin

Reputation: 3360

Since my client changed his password, the certificate needed to be installed again.

That's it.

Upvotes: 1

Related Questions