EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signing XML document at client side in browser

Also by EldoS: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.
#20151
Posted: 05/15/2012 05:42:26
by Vladimir Tchalkov (Standard support level)
Joined: 07/08/2010
Posts: 3

Hi,

I'm trying to create a small prtotype that should do the following:
- prepare a XML document at server
- Sign this document at client side in browser with a smart card client certificate. this certificate is not known in advance.
- Get the result back to server and create a detached XML siganture. the signature should contain the public part of the certificate.

I reviewed the sample ASPNet_Distributed, however I cannot change it to work with XML documents.
I understand that I have to call GenerateSignatureAsync and InitiateAsyncSign but I could not find any documentation how to use them.
what is the correct way to do this?

I'm using the latest SecureBlackBox evaluation.

Vladimir
#20152
Posted: 05/15/2012 05:56:41
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

Documentation for Distributed Cryptography add-on is not ready yet however I believe these articles will help you: https://www.eldos.com/security/articles/65-329.php
#20153
Posted: 05/15/2012 07:37:22
by Dmytro Bogatskyy (EldoS Corp.)

Quote
I understand that I have to call GenerateSignatureAsync and InitiateAsyncSign but I could not find any documentation how to use them.

Also you would need to call CompleteAsyncSign method to finalize signing.
Please see a sample below:
Code
EmulateDistribSigningXML("sample.xml", "sample-presigned.xml", "sample-signed.xml",
  "xml-state-01.xml", "xml-state-02.xml",
  "cert.pfx", "password");

public static void EmulateDistribSigningXML(string SourceFileName, string TempFileName, string DestFileName,
    string StateFileName, string StateOutFileName, string CertFileName, string CertPassword)
{
    SBDCEnc.Unit.SetDefaultDCEncoding(new SBDCXMLEnc.TElDCXMLEncoding());

    SBDC.TElDCAsyncState State = null;
    using (TElXMLDOMDocument Doc = new TElXMLDOMDocument())
    {
        using (FileStream F = new FileStream(SourceFileName, FileMode.Open, FileAccess.Read))
        {
            Doc.LoadFromStream(F);
        }

        TElXMLKeyInfoX509Data X509KeyData = null;
        TElXMLSigner Signer = new TElXMLSigner();
        try
        {
            Signer.SignatureType = SBXMLSec.Unit.xstEnveloped;
            Signer.SignatureMethodType = SBXMLSec.Unit.xmtSig;
            Signer.SignatureMethod = SBXMLSec.Unit.xsmRSA_SHA512;
            Signer.IncludeKey = true;

            TElXMLReference Ref = new TElXMLReference();
            Ref.DigestMethod = SBXMLSec.Unit.xdmSHA512;
            Ref.URINode = Doc.DocumentElement;
            Ref.URI = "";
            Ref.TransformChain.Add(new SBXMLTransform.TElXMLEnvelopedSignatureTransform());
            Signer.References.Add(Ref);

            X509KeyData = new TElXMLKeyInfoX509Data(true);
            X509KeyData.Certificate = new TElX509Certificate();

            using (TElX509Certificate Cert = new TElX509Certificate())
            {
                using (FileStream F = new FileStream(CertFileName, FileMode.Open, FileAccess.Read))
                {
                    Cert.LoadFromStreamPFX(F, CertPassword, 0);
                    Cert.Clone(X509KeyData.Certificate, false);
                }
            }

            Signer.KeyData = X509KeyData;

            Signer.UpdateReferencesDigest();
            Signer.GenerateSignatureAsync();

            TElXMLDOMNode SigNode = Doc.DocumentElement;
            State = Signer.InitiateAsyncSign(ref SigNode);
        }
        finally
        {
            Signer.Dispose();
            if (X509KeyData != null)
                X509KeyData.Dispose();
        }

        using (FileStream F = new FileStream(TempFileName, FileMode.Create, FileAccess.ReadWrite))
        {
            Doc.SaveToStream(F, SBXMLDefs.Unit.xcmNone, "");
        }
    }

    // saving the obtained state to file for debug purposes
    using (FileStream F = new FileStream(StateFileName, FileMode.Create, FileAccess.ReadWrite))
    {
        State.SaveToStream(F, null);
    }

    State.Dispose();

    // processing the state by server
    SBDCPKI.TElDCX509SignOperationHandler SigHandler = new SBDCPKI.TElDCX509SignOperationHandler();
    SigHandler.CertStorage = new SBCustomCertStorage.TElMemoryCertStorage();
    using (FileStream F = new FileStream(CertFileName, FileMode.Open, FileAccess.Read))
    {
        SigHandler.CertStorage.LoadFromStreamPFX(F, CertPassword, 0);
    }

    SBDCServer.TElDCStandardServer Server = new SBDCServer.TElDCStandardServer();
    Server.AddOperarionHandler(SigHandler);
    using (FileStream F = new FileStream(StateFileName, FileMode.Open, FileAccess.Read))
    {
        using (FileStream OutF = new FileStream(StateOutFileName, FileMode.Create, FileAccess.ReadWrite))
        {
            Server.Process(F, OutF, null, null);
        }
    }

    // finalizing the signature
    State = new SBDC.TElDCAsyncState();
    using (FileStream F = new FileStream(StateOutFileName, FileMode.Open, FileAccess.Read))
    {
        State.LoadFromStream(F, null);
    }

    using (TElXMLDOMDocument Doc = new TElXMLDOMDocument())
    {
        using (FileStream F = new FileStream(TempFileName, FileMode.Open, FileAccess.Read))
        {
            Doc.LoadFromStream(F);
        }

        using (TElXMLSigner Signer = new TElXMLSigner())
        {
            Signer.CompleteAsyncSign(Doc, State);
        }

        using (FileStream F = new FileStream(DestFileName, FileMode.Create, FileAccess.ReadWrite))
        {
            Doc.SaveToStream(F, SBXMLDefs.Unit.xcmNone, "");
        }
    }

    State.Dispose();
}
#20155
Posted: 05/15/2012 13:02:32
by Vladimir Tchalkov (Standard support level)
Joined: 07/08/2010
Posts: 3

Thanks a lot for the sample.

One more question.
By looking at lines 34-46 it looks like the server should know in advance about the certificate that will be used by the client.
Is it possible to avoid this? In our scenario we do not know in advance the certificate that will be used by the client.

What will happen if the client signs a certificate that is different than the one used before InitiateAsyncSign?
#20157
Posted: 05/15/2012 16:52:01
by Dmytro Bogatskyy (EldoS Corp.)

Quote
By looking at lines 34-46 it looks like the server should know in advance about the certificate that will be used by the client.

You can omit those lines.
Then, in final stage (after line 109) you can add KeyInfo element (if needed) in the following way:
Code
  Signer.Signature.KeyInfo.SetKeyData(X509KeyData);
  TElXMLDOMElement El = Signer.Signature.KeyInfo.SaveToXML(Doc);
  Signer.Signature.XMLElement.AppendChild(El);

The only thing that in this case a KeyInfo element couldn't be signed (but usually you don't need this).
#20163
Posted: 05/16/2012 06:30:24
by Vladimir Tchalkov (Standard support level)
Joined: 07/08/2010
Posts: 3

Thanks a lot. It works perfectly now.

One last question - is there a way to localize the interface of Java or ActiveX component to another language?
#20164
Posted: 05/16/2012 06:36:27
by Vsevolod Ievgiienko (EldoS Corp.)

Hello.

Yes you can do this by editing these modules code.
#20166
Posted: 05/16/2012 06:47:01
by Eugene Mayevski (EldoS Corp.)

Source code of client-side modules is available to customers who have a license for Distributed Cryptography add-on. Please note that this is a separate license which is not included with any existing package and is purchased separately. Please contact us privately (eg. via HelpDesk) or e-mail) for details on upgrading your existing license.


Sincerely yours
Eugene Mayevski
#21085
Posted: 08/21/2012 02:26:22
by janjoris van der Lei (Priority Standard support level)
Joined: 08/16/2012
Posts: 14

Quote
Dmytro Bogatskyy wrote:
Quote
By looking at lines 34-46 it looks like the server should know in advance about the certificate that will be used by the client.

You can omit those lines.
Then, in final stage (after line 109) you can add KeyInfo element (if needed) in the following way:
Code
  Signer.Signature.KeyInfo.SetKeyData(X509KeyData);
  TElXMLDOMElement El = Signer.Signature.KeyInfo.SaveToXML(Doc);
  Signer.Signature.XMLElement.AppendChild(El);

The only thing that in this case a KeyInfo element couldn't be signed (but usually you don't need this).


How do we get the certficate from the client? I do the code before InitiateAsyncSign. Then the applet pops up and asks to choose the certificate, with a smart card I am also asked for a pin code. But I am stuck after that step. I return to the server code but I don't know what to do then. I guess I should create a TElDCX509SignOperationHandler but how do I get the certificate from the client in this handler to complete the signing?
#21097
Posted: 08/21/2012 10:49:22
by Ken Ivanov (EldoS Corp.)

Janjoris,

Your understanding is almost correct. After getting a certificate from the user, you should create an instance of ElDCStandardServer class (general DC processing class) and attach an instance of ElDCX509SignOperationHandler class (certificate-based signing handler class) to the former. You should also let the created ElDCX509SignOperationHandler object know which certificate(s) to use with setKeyStore() and setSigningCertificate() methods. Upon completion of the initialization, call the Process() method of the server:

Code
ElDCStandardServer server = new ElDCStandardServer();
ElDCX509SignOperationHandler handler = new ElDCX509SignOperationHandler();
handler.setKeyStore(certificates);
handler.setSigningCertificate(signingCert, signingKey);
server.addOperationHandler(handler);
server.process(inStream, outStream);


The handler expects key store, certificate and private key to be native Java security objects (java.security.*).
Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.

Reply

Statistics

Topic viewed 6719 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!