On 9/5/12 6:55 AM, Hariprasath wrote:
> Hi,
>           I have applied signature in my XML which already contains a 
> signature. 
> The problem is when i try to verify the applied signature i get the error 
> saying 
> that the signature is bad. Pls help. 
> 

How are you creating the signature? You should be signing the existing
SignatureValue element, and then inserting the 2nd signature as a
SignatureProperty. See the attached example (using JSR 105) as an example that
might be helpful and you can adapt to your needs.

--Sean
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.*;
import java.util.Collections;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This is a simple example of counter-signing an XML Signature using the 
 * JSR 105 API. The resulting counter-signature will be added as a 
 * SignatureProperty object of the existing XML Signature that has been
 * counter-signed.
 */
public class CounterSign {

    //
    // Synopis: java CounterSign [input] [output]
    //
    //   where "input" is the name of a file containing a signature that
    //   is to be counter-signed, and "output" is the name of a file that will 
    //   contain the generated counter-signature. If output is not specified, 
    //   standard output will be used.
    //
    public static void main(String[] args) throws Exception {

        // Instantiate the document containing the signature
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc =
            dbf.newDocumentBuilder().parse(new FileInputStream(args[0]));

        // Find Signature element
        NodeList nl =
            doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        if (nl.getLength() == 0) {
            throw new Exception("Cannot find Signature element");
        }
        Element sig1Elem = (Element) nl.item(0);

        // First, create the DOM XMLSignatureFactory that will be used to 
        // unmarshal and generate the counter XMLSignature
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

        // Create a DOMValidateContext 
        DOMValidateContext valContext = new DOMValidateContext(sig1Elem);

        // unmarshal the XMLSignature
        XMLSignature signature1 = fac.unmarshalXMLSignature(valContext);

        // Now we are going to create the counter signature

        // First, create a Reference to the unmarshalled SignatureValue
        Reference ref = fac.newReference("#" + signature1.getSignatureValueId(),
            fac.newDigestMethod(DigestMethod.SHA1, null));

        // Create the SignedInfo
        SignedInfo si = fac.newSignedInfo(
            fac.newCanonicalizationMethod
                (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, null), 
            fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
            Collections.singletonList(ref));

        // Create a DSA KeyPair
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(512);
        KeyPair kp = kpg.generateKeyPair();

        // Create a KeyValue containing the DSA PublicKey that was generated
        KeyInfoFactory kif = fac.getKeyInfoFactory();
        KeyValue kv = kif.newKeyValue(kp.getPublic());

        // Create a KeyInfo and add the KeyValue to it
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

        // Create the XMLSignature (but don't sign it yet)
        XMLSignature signature = fac.newXMLSignature(si, ki); 

        // insert to-be-signed counter-signature in a SignatureProperties elem
        // find insertion point
        Element objElem = null;
        Element propsElem = null;
        Element propElem = doc.createElementNS
            (XMLSignature.XMLNS, "SignatureProperty");
        propElem.setAttributeNS
            (XMLSignature.XMLNS, "Target", "#" + signature1.getId());
        nl = sig1Elem.getElementsByTagNameNS(XMLSignature.XMLNS, "Object");
        if (nl.getLength() == 0) {
            objElem = doc.createElementNS(XMLSignature.XMLNS, "Object");
            propsElem = doc.createElementNS
                (XMLSignature.XMLNS, "SignatureProperties");
            propsElem.appendChild(propElem);
            objElem.appendChild(propsElem);
            sig1Elem.appendChild(objElem);
        } else {
            objElem = (Element) nl.item(0);
            nl = objElem.getElementsByTagNameNS
                (XMLSignature.XMLNS, "SignatureProperties");
            if (nl.getLength() == 0) {
                propsElem = doc.createElementNS
                    (XMLSignature.XMLNS, "SignatureProperties");
                propsElem.appendChild(propElem);
                objElem.appendChild(propsElem);
            } else {
                propsElem = (Element) nl.item(0);
                propsElem.appendChild(propElem);
            }
        }

        // Create a DOMSignContext and specify the DSA PrivateKey for signing
        // and the document location of the XMLSignature
        DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), propElem);

        // Lastly, generate the enveloping signature using the PrivateKey
        signature.sign(dsc);

        // output the resulting document
        OutputStream os;
        if (args.length > 1) {
           os = new FileOutputStream(args[1]);
        } else {
           os = System.out;
        }

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));
    }
}

Reply via email to