Re: XML Signature, how to sign?

From: iksrazal (iksrazal_at_terra.com.br)
Date: 11/05/03


Date: 5 Nov 2003 04:05:41 -0800


"Darek" <interdarekb@NOSPAMpoczta.onet.pl> wrote in message news:<bo94am$9qh$1@korweta.task.gda.pl>...
> Hello!
>
> I have been trying to sign XML document "sample.xml" located eg. in
> http://localhost/sample.xml, using Apache XML Security package from
> http://xml.apache.org/security/Java/. I am using NullURIReferenceResolver
> class to create URI for my "sample.xml" document. Unfortunately, when I was
> trying to compile my source code, I got the following exceptions:
>
>
> -----------
> Exceptions in thread "main"
> org.apache.xml.security.signature.XMLSignatureException: The XPath is not in
> the same document as the context node
> Orginal Exception was
> org.apache.xml.security.signature.ReferenceNotInitialized
> ...
> Orginal Exception was
> org.apache.xml.security.transforms.TransformationException: The XPath is not
> in the same document as the context node
> ....
> -----------
> Please help. I don't really know what I should fix in this code to make it
> work properly.
>
> In advace, thanks a lot for support & helping hand.
>
>
> best regards,
> Darek
>
> PS.
> Here is the source code:
>
> package org.apache.xml.security.samples.signature;
>
> import java.io.*;
> import java.lang.reflect.*;
> import java.security.*;
> import java.security.cert.*;
> import java.util.*;
> import javax.xml.transform.TransformerException;
> import org.apache.xpath.XPathAPI;
> import org.w3c.dom.*;
> import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
> import org.apache.xml.security.c14n.*;
> import org.apache.xml.security.exceptions.XMLSecurityException;
> import org.apache.xml.security.signature.*;
> import org.apache.xml.security.keys.*;
> import org.apache.xml.security.keys.content.*;
> import org.apache.xml.security.keys.content.x509.*;
> import org.apache.xml.security.keys.keyresolver.*;
> import org.apache.xml.security.keys.storage.*;
> import org.apache.xml.security.keys.storage.implementations.*;
> import org.apache.xml.security.utils.*;
> import org.apache.xml.security.transforms.*;
> import org.apache.xml.security.Init;
> import org.apache.xml.security.samples.signature.NullURIReferenceResolver;
> import org.apache.xml.serialize.*;
>
> public class myCreateSignature {
>
> static org.apache.log4j.Category cat =
>
> org.apache.log4j.Category.getInstance(CreateSignature.class.getName());
>
> static {
> org.apache.xml.security.Init.init();
> }
>
> public static void main(String unused[]) throws Exception {
>
> String keystoreType = "JKS";
> String keystoreFile =
> "data/org/apache/xml/security/samples/input/keystore.jks";
> String keystorePass = "xmlsecurity";
> String privateKeyAlias = "test";
> String privateKeyPass = "xmlsecurity";
> String certificateAlias = "test";
>
> // create DOM document
> javax.xml.parsers.DocumentBuilderFactory dbf =
> javax.xml.parsers.DocumentBuilderFactory.newInstance();
>
> dbf.setNamespaceAware(true);
> javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
> org.w3c.dom.Document doc = db.newDocument();
>
> // output file "signature.XML"
> java.io.File signatureFile =
> new File("signature.xml");
>
> // URI
> String BaseURI = signatureFile.toURL().toString();
>
> // prefix
>
> org.apache.xml.security.utils.Constants.setSignatureSpecNSprefix("ds");
>
> // signature
> org.apache.xml.security.signature.XMLSignature sig =
> new XMLSignature(doc, BaseURI,
> XMLSignature.ALGO_ID_SIGNATURE_DSA);
>
> // add signature into document
> doc.appendChild(sig.getElement());
>
> // resolver
> String xml_to_sign = http://localhost/sample.xml;
>
> org.apache.xml.security.samples.signature.NullURIReferenceResolver
> null_URI =
> new NullURIReferenceResolver(xml_to_sign.getBytes());
>
> // add resolver to signature
> sig.addResourceResolver(null_URI);
>
> // transformations i canonicalization C14n
> org.apache.xml.security.transforms.Transforms transforms =
> new Transforms(doc);
>
> // make transformations
> transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
> transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
>
> // add document "http://localhost/sample.xml" to signature
> sig.addDocument(xml_to_sign, transforms,
> Constants.ALGO_ID_DIGEST_SHA1);
>
> // contener of certificates and keys
> java.security.KeyStore ks = KeyStore.getInstance(keystoreType);
>
> java.io.FileInputStream fis =
> new FileInputStream(keystoreFile);
>
> // initialization contener
> ks.load(fis, keystorePass.toCharArray());
>
> // certificate X509
> java.security.cert.X509Certificate cert =
> (X509Certificate) ks.getCertificate(certificateAlias);
>
> // public key
> java.security.PublicKey publicKey = cert.getPublicKey();
>
> // private key
> java.security.PrivateKey privateKey =
> (PrivateKey) ks.getKey(privateKeyAlias,
> privateKeyPass.toCharArray());
>
> sig.addKeyInfo(cert);
> sig.addKeyInfo(publicKey);
> System.out.println("Start signing");
> sig.sign(privateKey);
> System.out.println("Finished signing");
>
> // save into output file "signature.xml" DOM document
> java.io.FileOutputStream fos =
> new FileOutputStream(signatureFile);
> XMLUtils.outputDOMc14nWithComments(doc, fos);
> fos.close();
>
> System.out.println("Wrote signature to " + BaseURI);
> }
>
> }

Hello,

What I can help with is show you how I used XML Signature from apache.
Yes, I had lots problems too. Hope this helps.

public static void sign(Document doc, String keystore, String
storetype, String storepass, String alias, String keypass) throws
Exception
  {
    try
    {
      //Add this header to the SOAP message if it does not exist
      String soap_header =
"http://schemas.xmlsoap.org/soap/envelope/";
      // Initialize the library
      org.apache.xml.security.Init.init();

      /******************* XML SIGNATURE INIT ***********************
       Append the signature element to proper location before signing
      ***************************************************************/
      // Look for the SOAP header
      Element headerElement = null;
      NodeList nodes = doc.getElementsByTagNameNS (soap_header,
"Header");
      //No nodes are expected to be found (length of zero) - add
      //header here.
      if(nodes.getLength() == 0)
      {
         System.out.println("Adding a SOAP Header Element");
         headerElement = doc.createElementNS (soap_header, "Header");
         nodes = doc.getElementsByTagNameNS (soap_header, "Envelope");
         if(nodes != null)
         {
            Element envelopeElement = (Element)nodes.item(0);
            headerElement.setPrefix(envelopeElement.getPrefix());
            envelopeElement.appendChild(headerElement);
         }
      }
      else
      {
        //This shouldn't happen unless explicity done elsewhere
        System.out.println("Found " + nodes.getLength() + " SOAP
Header elements.");
        headerElement = (Element)nodes.item(0);
      }

      // http://xml-security is the base-uri, which needs to be
      //unique within document
      XMLSignature sig = new XMLSignature(doc, "http://xml-security",
XMLSignature.ALGO_ID_SIGNATURE_DSA);
      // Add SOAP Body to XML Signature
      headerElement.appendChild(sig.getElement());
      // Due to the bug in the Apache security lib, it does not allow
      // us to sign whole message and make "enveloped-signature"
      // transform - strictly part of the specification.
      // Only sign the body - IT IS NOT CONFORMED TO THE SPEC!!!!!!
      //
      // Neat trick: since the XMLSignature is actually a part of the
      // SOAP XML document, the SOAP body is referenced as a URI
      // fragment
      sig.addDocument("#Body");
      /******************* END XML SIGNATURE INIT
*********************/

      /******************* X.509 Certificate INIT *****************/
      FileInputStream fis = new FileInputStream(keystore);
      java.security.KeyStore ks =
java.security.KeyStore.getInstance(storetype);
      ks.load(fis, storepass.toCharArray());

      // commented out for obvious reasons
      //System.err.println("ClientSecurity::sign -- alias: " + alias);
      //System.err.println("ClientSecurity::sign -- keypass: " +
keypass);
      PrivateKey privateKey = (PrivateKey)ks.getKey(alias,
keypass.toCharArray());
      X509Certificate cert =
(X509Certificate)ks.getCertificate(alias);
      /***************** END X.509 Certificate INIT
*******************/

      /****************** SIGN THE FUCKER *******************/
      sig.addKeyInfo(cert);
      sig.addKeyInfo(cert.getPublicKey());
      // Sign the XML Signature document with our private key
      sig.sign(privateKey);
      /****************** FUCKER SIGNED *********************/
    }
    catch (Exception e)
    {
      System.err.println("ClientSecurity::sign -- Exception: ");
      e.printStackTrace();
    }
  }


Quantcast