In a Dotnet6 console application, I'm trying to digitally sign an xml string using a p12 file. My code is as follows:

static System.Security.Cryptography.X509Certificates.X509Certificate2 LoadCertificate()
{
    string certPath = Environment.CurrentDirectory + "/Certificates/myCertificate.p12";
    string certPass = "thePassword";

    System.Security.Cryptography.X509Certificates.X509Certificate2 returnX509 = null; 

    try
    {
        returnX509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, certPass);
    }
    catch
    {
        Console.WriteLine("Failed to obtain certificate"); 
    }

    return returnX509;
}


static void SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert)
{

    RSACryptoServiceProvider rsaKey = uidCert.PrivateKey as RSACryptoServiceProvider;

    // Check arguments. 
    if (xmlDoc == null)
        throw new ArgumentException("xmlDoc");
    if (rsaKey == null)
        throw new ArgumentException("Key");

    // Create a SignedXml object.
    SignedXml signedXml = new SignedXml(xmlDoc);

    // Add the key to the SignedXml document.
    signedXml.SigningKey = rsaKey;


    // Create a reference to be signed.
    Reference reference = new Reference();
    reference.Uri = "";

    // Add an enveloped transformation to the reference.
    XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
    reference.AddTransform(env);

    // Add the reference to the SignedXml object.
    signedXml.AddReference(reference);


    // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
    KeyInfo keyInfo = new KeyInfo();

    KeyInfoX509Data clause = new KeyInfoX509Data();
    clause.AddSubjectName(uidCert.Subject);
    clause.AddCertificate(uidCert);
    keyInfo.AddClause(clause);
    signedXml.KeyInfo = keyInfo;

    // Compute the signature.
    signedXml.ComputeSignature();

    // Get the XML representation of the signature and save 
    // it to an XmlElement object.
    XmlElement xmlDigitalSignature = signedXml.GetXml();

    System.Console.WriteLine(signedXml.GetXml().InnerXml);

    // Append the element to the XML document.
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));


} 

var cert = LoadCertificate(); // that works ok
var key2 = cert.GetRSAPrivateKey(); // here returns null
var key = cert.PrivateKey; // here I get error

The code I found for signing xml, uses the private key. However when I try to access the private key, it throws System.NotSupportedException: 'The certificate key algorithm is not supported.'. I also tried GetRSAPrivateKey() method but it returns null and SignXml method throws exception. How can I access that key?

0

There are 0 best solutions below