XML Signature, how to sign?

D

Darek

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);
}

}
 
I

iksrazal

Darek said:
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();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top