0

I've been give a private key, public key and a certificate to try and generate a signature for an SSO application, I've been struggling with this for a while now and I've think I've finally managed to get some code close to working as needed. I made a post a while back here: iDP connecting to SP SAML / SSO which has helped me get in the right direction.

However I am still unsure on how I meant to be signing this signature, all the code I seem to come by says I need to use the .Net class X509Certificate which usually tried to load in another file, however the certificate is in the assertion file itself.

<ds:X509Data>
    <ds:X509Certificate>X509Certificate Goes Here</ds:X509Certificate>
</ds:X509Data>

I have this method here:

  private SignedXml SignSignature(XmlDocument assertionDoc, string uri, string digest)
    {
        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        SignedXml signedXml = new SignedXml(assertionDoc);
        Reference reference = new Reference();

        signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
        signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

        reference.Uri = uri;     

        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
        reference.DigestValue = Encoding.ASCII.GetBytes(digest);

        signedXml.AddReference(reference);
        signedXml.SigningKey = rsaKey;

        HMACSHA256 key = new HMACSHA256(Encoding.ASCII.GetBytes(PrivateKey));

        signedXml.ComputeSignature(key);

        return signedXml;
    }

Which is what I am using to sign SignatureValue of the document, however I am only making use of the private key in the SHA256 class and not the certificate, I'm not even sure if I am using the private key correctly, overall I think I am making this more complicated than it needs to be and hopefully someone from here can assist me.

1 Answers1

0

When you sign an assertion, you only need to use the private key of a certificate which is the case of your code.

However, usually the public key of the certificate is inserted as keyinfo into the signature to notify a receiver. This ends up as the ds:X509Data section you mentioned above. In order to do that, you need to add some more lines of code into the method above. You can find sample code at: https://github.com/Safewhere/CHTestSigningService/blob/86a66950d1ffa5208b8bf80d03868a073ba29f12/Kombit.Samples.CHTestSigningService/Code/TokenSigningService.cs#L344 (notice line 361, 362, and 368).

Thuan
  • 1,618
  • 1
  • 10
  • 21