[jdom-interest] Signing a JDOM Document
Alistair Young
alistair at smo.uhi.ac.uk
Wed Dec 1 15:05:11 PST 2004
Looks good Mauricio, I'll give it a run when I'm back in the office. I
suspect I've hit the namespace thingy again. It's sort of "losing the
scope" of default namespaces when building the JDOM from the w3c. Perhaps
if I qualify every single element in the w3c the problem will go away but
if they reappear as fully qualified on the wire then it's a trade-off
between bandwidth or not working at all!
Alistair
--
Alistair Young
Senior Software Engineer
UHI at Sabhal Mòr Ostaig
Isle of Skye
Scotland
> 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/
>
> _______________________________________________
> To control your jdom-interest membership:
> http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com
>
More information about the jdom-interest
mailing list