Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C#, sign an xml with a x.509 certificate and check the signature

I'm trying to sign an XML file using a x.509 certificate, I can use the private key to sign the document and then use the CheckSignature method (it has an overload that receives a certificate as parameter) to verify the signature.

The problem is that the user who validates the signature must have the certificate, my concern is, if the user has the certificate then he has access to the private key, and as I understand, this is private and should be available only to the user who signs.

What am I missing?

Thanks for your help.

like image 447
willvv Avatar asked Jul 28 '09 18:07

willvv


People also ask

What does %= mean in C?

%= Modulus AND assignment operator. It takes modulus using two operands and assigns the result to the left operand. C %= A is equivalent to C = C % A.

What is '~' in C language?

In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...

What does the || mean in C?

The logical OR operator ( || ) returns the boolean value true if either or both operands is true and returns false otherwise.

What is operators in C?

C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.


2 Answers

In .NET, If you get your X509 cert from a .pfx file, like this:

 X509Certificate2 certificate = new X509Certificate2(certFile, pfxPassword);
 RSACryptoServiceProvider rsaCsp = (RSACryptoServiceProvider) certificate.PrivateKey;   

Then you can export the public key portion like so:

 rsaCsp.ToXmlString(false);

The "false" part says, only export the public piece, don't export the private piece. (doc for RSA.ToXmlString)

And then in the verifying application, use

 RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
 csp.FromXmlString(PublicKeyXml);
 bool isValid = VerifyXml(xmlDoc, rsa2);

And the VerifyXml calls CheckSignature(). It looks something like this:

private Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
    // Create a new SignedXml object and pass it
    // the XML document class.
    var signedXml = new System.Security.Cryptography.Xml.SignedXml(Doc);

    // Find the "Signature" node and create a new XmlNodeList object.
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

    // Throw an exception if no signature was found.
    if (nodeList.Count <= 0)
    {
        throw new CryptographicException("Verification failed: No Signature was found in the document.");
    }

    // Though it is possible to have multiple signatures on 
    // an XML document, this app only supports one signature for
    // the entire XML document.  Throw an exception 
    // if more than one signature was found.
    if (nodeList.Count >= 2)
    {
        throw new CryptographicException("Verification failed: More that one signature was found for the document.");
    }

    // Load the first <signature> node.  
    signedXml.LoadXml((XmlElement)nodeList[0]);

    // Check the signature and return the result.
    return signedXml.CheckSignature(Key);
}
like image 61
Cheeso Avatar answered Sep 18 '22 16:09

Cheeso


Any certificate has a public and a private part. You only send around the public part. Just open any SSL enabled website in your browser, click on the padlock symbol and have a look at their certificate.

like image 5
chris166 Avatar answered Jan 01 '70 00:01

chris166