Signing.java Source code

Java tutorial

Introduction

Here is the source code for Signing.java

Source

    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.SecureRandom;
    import java.util.Collections;

    import javax.xml.crypto.dsig.CanonicalizationMethod;
    import javax.xml.crypto.dsig.DigestMethod;
    import javax.xml.crypto.dsig.Reference;
    import javax.xml.crypto.dsig.SignatureMethod;
    import javax.xml.crypto.dsig.SignedInfo;
    import javax.xml.crypto.dsig.XMLSignature;
    import javax.xml.crypto.dsig.XMLSignatureFactory;
    import javax.xml.crypto.dsig.dom.DOMSignContext;
    import javax.xml.crypto.dsig.dom.DOMValidateContext;
    import javax.xml.crypto.dsig.keyinfo.KeyInfo;
    import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
    import javax.xml.crypto.dsig.keyinfo.KeyValue;
    import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.soap.MessageFactory;
    import javax.xml.soap.Name;
    import javax.xml.soap.SOAPBody;
    import javax.xml.soap.SOAPBodyElement;
    import javax.xml.soap.SOAPEnvelope;
    import javax.xml.soap.SOAPHeader;
    import javax.xml.soap.SOAPHeaderElement;
    import javax.xml.soap.SOAPMessage;
    import javax.xml.soap.SOAPPart;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.sax.SAXSource;
    import javax.xml.transform.stream.StreamResult;

    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.xml.sax.InputSource;

    public class Signing {

        public static void main(String[] args) throws Exception {
            SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope soapEnvelope = soapPart.getEnvelope();

            SOAPHeader soapHeader = soapEnvelope.getHeader();
            SOAPHeaderElement headerElement = soapHeader.addHeaderElement(soapEnvelope.createName("Signature",
                    "SOAP-SEC", "http://schemas.xmlsoap.org/soap/security/2000-12"));

            SOAPBody soapBody = soapEnvelope.getBody();
            soapBody.addAttribute(
                    soapEnvelope.createName("id", "SOAP-SEC", "http://schemas.xmlsoap.org/soap/security/2000-12"),
                    "Body");
            Name bodyName = soapEnvelope.createName("FooBar", "z", "http://example.com");
            SOAPBodyElement gltp = soapBody.addBodyElement(bodyName);

            Source source = soapPart.getContent();
            Node root = null;
            if (source instanceof DOMSource) {
                root = ((DOMSource) source).getNode();
            } else if (source instanceof SAXSource) {
                InputSource inSource = ((SAXSource) source).getInputSource();
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                dbf.setNamespaceAware(true);
                DocumentBuilder db = null;

                db = dbf.newDocumentBuilder();

                Document doc = db.parse(inSource);
                root = (Node) doc.getDocumentElement();
            }

            dumpDocument(root);

            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
            kpg.initialize(1024, new SecureRandom());
            KeyPair keypair = kpg.generateKeyPair();

            XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance();
            Reference ref = sigFactory.newReference("#Body", sigFactory.newDigestMethod(DigestMethod.SHA1, null));
            SignedInfo signedInfo = sigFactory.newSignedInfo(
                    sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                            (C14NMethodParameterSpec) null),
                    sigFactory.newSignatureMethod(SignatureMethod.DSA_SHA1, null), Collections.singletonList(ref));
            KeyInfoFactory kif = sigFactory.getKeyInfoFactory();
            KeyValue kv = kif.newKeyValue(keypair.getPublic());
            KeyInfo keyInfo = kif.newKeyInfo(Collections.singletonList(kv));

            XMLSignature sig = sigFactory.newXMLSignature(signedInfo, keyInfo);

            System.out.println("Signing the message...");
            PrivateKey privateKey = keypair.getPrivate();
            Element envelope = getFirstChildElement(root);
            Element header = getFirstChildElement(envelope);
            DOMSignContext sigContext = new DOMSignContext(privateKey, header);
            sigContext.putNamespacePrefix(XMLSignature.XMLNS, "ds");
            sigContext.setIdAttributeNS(getNextSiblingElement(header),
                    "http://schemas.xmlsoap.org/soap/security/2000-12", "id");
            sig.sign(sigContext);

            dumpDocument(root);

            System.out.println("Validate the signature...");
            Element sigElement = getFirstChildElement(header);
            DOMValidateContext valContext = new DOMValidateContext(keypair.getPublic(), sigElement);
            valContext.setIdAttributeNS(getNextSiblingElement(header),
                    "http://schemas.xmlsoap.org/soap/security/2000-12", "id");
            boolean valid = sig.validate(valContext);

            System.out.println("Signature valid? " + valid);
        }

        private static void dumpDocument(Node root) throws TransformerException {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(new DOMSource(root), new StreamResult(System.out));
        }

        private static Element getFirstChildElement(Node node) {
            Node child = node.getFirstChild();
            while ((child != null) && (child.getNodeType() != Node.ELEMENT_NODE)) {
                child = child.getNextSibling();
            }
            return (Element) child;
        }

  public static Element getNextSiblingElement(Node node) {
    Node sibling = node.getNextSibling();
    while ((sibling != null) && (sibling.getNodeType() != Node.ELEMENT_NODE)) {
      sibling = sibling.getNextSibling();
    }
    return (Element) sibling;
  }
    }
    /*
    
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header>
    <SOAP-SEC:Signature xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12"/>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body">
    <z:FooBar xmlns:z="http://example.com"/>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    Signing the message...
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header>
    <SOAP-SEC:Signature xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12"/>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
    <ds:Reference URI="#Body">
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <ds:DigestValue>9x0mZhajy9dHKuIXh7bm0khuC7M=</ds:DigestValue>
    </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>CiKztXFr2HnE1ul1S5OrJpiYCV46MJ9jEiDaU7AkAiCsgkTDxAhzyA==</ds:SignatureValue>
    <ds:KeyInfo>
    <ds:KeyValue>
    <ds:DSAKeyValue>
    <ds:P>/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA
    HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu
    K2HXKu/yIgMZndFIAcc=</ds:P>
    <ds:Q>l2BQjxUjC8yykrmCouuEC/BYHPU=</ds:Q>
    <ds:G>9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
    zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL
    Zl6Ae1UlZAFMO/7PSSo=</ds:G>
    <ds:Y>j9Jsiuc8WtI3LxN+wuVUHsCJ5i22tG2SBtiRzKoWrpso/Tk62TJRN7FNsWQ0lDqIqJrQt4GqzkHx
    yiRtmqm0xDsAd2ojzH1OZiGen+C8dsbAA4ydwmP1iz9UyAwevrdA/rhOAqgTUFv0ar9koh0aG/Wn
    iFrXoLYt5eVzpw/swT4=</ds:Y>
    </ds:DSAKeyValue>
    </ds:KeyValue>
    </ds:KeyInfo>
    </ds:Signature>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body">
    <z:FooBar xmlns:z="http://example.com"/>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    Validate the signature...
    Signature valid? true
    
    
    
    */

    #

    Code referenced from#Chapter 6-
    Extensible Markup

    Language (XML)
#Java 6 Platform Revealed
#by John Zukowski 
#ISBN: 1590596609
#http://www.apress.com/book/bookDisplay.html?bID=10109