Signing XML with MSXML5 and managed X509Certificate2 RRS feed

  • Question

  • Hi all,

    I have to write C# function, which recieves managed System.Security.Cryptography.X509Certificates.X509Certificate2 object and signs XML file using MSXML5.

    Due to internal limitations I cannot use pure .NET classes (SignedXml etc).

    Is there any way to use data, provided by X509Certificate2 object in order to build an IXMLDSigKey object acceptable by the Sign method of MSXML ?

    Thanks in advance,

    Thanks, Michael
    • Moved by Qi Samuel ZhangModerator Tuesday, February 22, 2011 1:31 AM Merging (From:XML in Windows (MSXML and XmlLite))
    Tuesday, March 17, 2009 9:17 AM


All replies

  • Hi,

    Following links talks about a lot about how to create IXMLDSigKey and how to manipulate X509Certificate2 object.

    1) http://msdn.microsoft.com/en-us/library/ms763799(VS.85).aspx
    2) http://msdn.microsoft.com/en-us/library/ms761363(VS.85).aspx
    3) http://blogs.msdn.com/alejacma/archive/2008/06/25/how-to-sign-and-verify-the-signature-with-net-and-a-certificate-c.aspx

    The code segments that creating IXMLDSigKey
    IXMLDigitalSignaturePtr xmldsig = NULL;     
    IXMLDSigKeyPtr dsigKey = xmldsig->createKeyFromCSP(CspType, "", keyContainer,0);     
    IXMLDSigKeyPtr signedKey = xmldsig->sign(dsigKey, KEYVALUE);    

    The code snip that getting csp object from X509Certificate2 object.
    // Get its associated CSP and public key  
                RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key;  
    // Get its associated CSP and private key  
                RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey; 

    Upon you got csp object, you can get the property/data that used to create IXMLDSigKey, I believe.

    Hope above information can help some. Please reply if still has problem.
    PS, according to my experience, msxml5 can't be called from c#/.net process directly, it is an unspported scenario. If you really want to do complete the task using c# + msxml5, I suggest you use 2 seperate processes to complete the task, one is the process running .net code, another is a daemon process/service running native code, while the daemon process that running msxml5 can process the request from the managed process.

    • Proposed as answer by Haowei Qin [MSFT] Monday, March 23, 2009 8:33 AM
    • Unproposed as answer by MishaSoft Monday, March 23, 2009 8:14 PM
    Wednesday, March 18, 2009 8:30 AM
  • Hi Haowei,

    Thanks for your reply!

    I must note that MSXML works great with .NET (C#) processes.
    .NET has an interoperability libraries allowing to call either pure unmanaged code (C/C++/MFC) or COM-based libraries.
    In case of COM, .NET supports both Late and Early bounds, while in the second case it generates an interoperability library containing .NET managed classes wrapping the COM classes. Memory management in the mixed (managed/unmanaged) processes is explained here: http://www.codeproject.com/KB/COM/cominterop.aspx

    What I'm trying to do is to implement a C# function, which gets X509Certificate2 managed object and signs a XML using this certificate and MSXML5 COM. It's absolutely clear, that I can't use managed certificate with MSXML directly.
    X509Certificate2 object is just a wrapper for the Microsoft CAPI PCCERT_CONTEXT structure. I even can retrieve the pointer to this structure

    My vision of the possible solution is:
    1. Use handle of the managed certificate (PCCERT_CONTEXT*) in order to create an unmanaged ICertificate2 object
    2. Extract signing key IXMLDSigKeyPtr object from the ICertificate2 and use this key for signing.

    Do you think it's possible? Any ideas?


    Thanks, Michael
    Monday, March 23, 2009 8:13 PM
  • Unfortunately, the use of MSXML is not supported in .NET applications. Please refer to http://support.microsoft.com/default.aspx/kb/815112.

    Please note that MSXML5 is designed for Office only instead of supporting ISV for signing.
    Tuesday, March 24, 2009 6:32 AM
  • Ops, I'm sorry Haowei, I didn't understand correctly what you said.
    It's important to me to provide a .NET - based assembly.
    Unfortunately, due to limitations in the native .NET SignedXml class, I cannot achieve my target with it.

    If I use C++.NET mixed code in order to call MSXML directly from C++ code (CoInitialize(), etc...), rather than using .NET interoperability, will such scenario be supported?

    Thanks, Michael.

    Thanks, Michael
    Tuesday, March 24, 2009 6:15 PM
  • To answer your question "If I use C++.NET mixed code in order to call MSXML directly from C++ code (CoInitialize(), etc...), rather than using .NET interoperability, will such scenario be supported?"

    --If you compiled the C++.Net (what ever language) into an assembly which must be run based on .Net Framework, then the scenario is NOT support. (may have problem due to the marshal/unmarshal objects between msxml5 and your managed code)

    --As samuel said, "MSXML5 is designed for Office only instead of supporting ISV for signing." So it is unsupported scenario to use msxml5 signature ourside of office apps. Which means you can use msxml5 BUT it is not supported by MS:)

    Again my suggestion to you:
    --If you really want to complete the JOB, I suggest you use 2 seperate processes to complete the task:
      . one process is .net process, another process running native code which using msxml5 to do signature.
      . You can use inter-process communication to pass xml data between the 2 processes.

    PS, if you use 2 processes solution to resolve your problem, you can directly send managed certificate object's data to the native process and do signature. While the native process will send back the xml data which has been signatured. Is this clear enough? Hope this piece of suggestion is useful to you.

    Tuesday, March 31, 2009 3:25 AM