[jdom-interest] Signing a JDOM Document

Mauricio García mmgh73 at hotmail.com
Wed Dec 1 12:47:53 PST 2004


I have the following method to sing a JDOM Document.  I use the same 
algorithm you said, and it works for me.  Maybe you can compare this code 
with your code. If you have coments, suggestions or questions, just do it!
Regards,

Mauricio García

	/**
	 * Firma con formato XMLSignature
	 * @param pKey
	 * @param cert
	 * @param ns
	 * @throws DocException
	 * @throws XMLSignatureException
	 * @throws XMLSecurityException
	 */
	public void sign(PrivateKey pKey, X509Certificate cert, Namespace ns)
		throws DocException,
				XMLSignatureException,
				XMLSecurityException {

		org.apache.xml.security.Init.init();


		// No se manejará ningún prefijo de Name Space para identificar los 
elementos de la firma
		Constants.setSignatureSpecNSprefix("");

		this.setFechaFirma(new Date());
		String baseUri = (ns!=null?ns.getURI():null);

		String alg = pKey.getAlgorithm();
		if (!alg.equals(cert.getPublicKey().getAlgorithm()))
			throw (new DocException(DocException.NOT_CORRESPONDING));

		// Para generar el XMLSignature, obtiene la data y la lleva a un objeto 
DOM
		// obteniendo la data desde el objeto JDOM.
		org.w3c.dom.Document doc;
		org.w3c.dom.Element root;
		try {
			javax.xml.parsers.DocumentBuilderFactory dbf = 
javax.xml.parsers.DocumentBuilderFactory.newInstance();
			dbf.setNamespaceAware(true);
			javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			XMLUtil.getRawXML(new 
Document(XMLUtil.applyNamespace(getDOMtoSign(),ns)), out);
			ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

			doc = db.parse(in);
			root = doc.getDocumentElement();
		} catch (Exception e) {
			throw (new DocException(DocException.MALFORMED));
		}

		// Genera el XML Signature con la información del objeto DOM
		XMLSignature sig = null;
		if (alg.equals("RSA")) {
			RSAPrivateKey rsaPrivKey = (RSAPrivateKey) pKey;
			RSAPublicKey rsaPubKey = (RSAPublicKey) cert.getPublicKey();

			if ( !rsaPrivKey.getModulus().equals(rsaPubKey.getModulus()) )
				throw new 
DocumentoTributarioException(DocumentoTributarioException.NOT_CORRESPONDING);

			sig = new XMLSignature(doc, baseUri, 
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);

		} else if (alg.equals("DSA")) {
			if (!(((DSAPrivateKey) pKey)
				.getParams()
				.getG()
				.equals(((DSAPublicKey) cert.getPublicKey()).getParams().getG())
				&& ((DSAPrivateKey) pKey).getParams().getP().equals(
					((DSAPublicKey) cert.getPublicKey()).getParams().getP())
				&& ((DSAPrivateKey) pKey).getParams().getQ().equals(
					((DSAPublicKey) cert.getPublicKey()).getParams().getQ())))
				throw (
					new 	DocumentoTributarioException(
						DocumentoTributarioException.NOT_CORRESPONDING));
			sig =
				new XMLSignature(
					doc,
					baseUri,
					XMLSignature.ALGO_ID_SIGNATURE_DSA);
		} else
			throw (
				new DocumentoTributarioException(
					DocumentoTributarioException.NOT_CORRESPONDING));

		root.appendChild(sig.getElement());

		// TODO: Ojo si es usado para todo.
		Transforms trans = new Transforms(doc);
		trans.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);

		if ( getId() != null )
			sig.addDocument("#" + getId(),trans);
		else
			sig.addDocument("",trans);

		X509Data xdata = new X509Data(doc);
		xdata.addCertificate(cert);
		sig.getKeyInfo().addKeyValue(cert.getPublicKey());
		sig.getKeyInfo().add(xdata);
		sig.sign(pKey);

		// TODO verficar que este sea el algoritmo correspondiente
		firmaAlg = sig.getKeyInfo().getPublicKey().getAlgorithm();

		// Asigna la firma generada al Elemento dentro de la clase que guarda la 
firma
		// TODO Verificar que el elemento Signature ya venga con el Namespace: 
http://www.w3.org/2000/09/xmldsig#
		ByteArrayOutputStream bous = new ByteArrayOutputStream();
		DOMBuilder docBuilder = new DOMBuilder();
		Document docOut = docBuilder.build(doc);

		setDOMFirma(docBuilder.build(doc).getRootElement().getChild(TAG_SIGNATURE,Namespace.getNamespace(SIGNATURE_NS)));
	}

>----------------------------------------------------------------------
>
>Message: 1
>Date: Wed, 1 Dec 2004 14:17:44 +0000
>From: Alistair Young <alistair at smo.uhi.ac.uk>
>Subject: [jdom-interest] Signing a JDOM Document
>To: jdom-interest at jdom.org
>Message-ID: <C498001D-43A3-11D9-B28A-000A95A7C766 at smo.uhi.ac.uk>
>Content-Type: text/plain; charset=US-ASCII; format=flowed
>
>Interesting follow on from my xmlns="" "problem". It's easily solved in
>JDOM by creating Elements with a namespace but the following is a
>problem now:
>1) Convert JDOM -> org.w3c.dom.Document
>2) Sign w3c Document
>3) Convert org.w3c.dom.Document -> JDOM
>
>3) causes the problem to reappear as <ds:Signature> is affected by
>presumably the Content cloning and adding? The end result is all
>"namespace scoped" elements, i.e. that are associated with a default
>namespace in their parent element, have xmlns="" added. Including the
><ds:Signature> !
>
>Am I doing something wrong?
>
>Alistair
>
>

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! 
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/



More information about the jdom-interest mailing list