title: XML Signature (Java)
body: <p>I am trying to sign a small xml that look like this:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;test/&gt;    
  </code></pre>
  
  <p>I must have something that look like this:</p>
  
  <pre><code>&lt;soapenv:Envelope xmlns:elc="http://schemas.datacontract.org/2004/07/Arise.and.shine" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"&gt;
      &lt;soapenv:Header&gt;
          &lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
              &lt;wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-F86143B2B1BBA025BF144915430086958"&gt;MYCERTIFICAT&lt;/wsse:BinarySecurityToken&gt;
              &lt;ds:Signature Id="SIG-F86143B2B1BBA025BF144915430086961" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
                  &lt;ds:SignedInfo&gt;
                      &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                          &lt;ec:InclusiveNamespaces PrefixList="elc soapenv tem" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
                      &lt;/ds:CanonicalizationMethod&gt;
                      &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
                      &lt;ds:Reference URI="#id-C412303BE3B390B3D114265182390669"&gt;
                          &lt;ds:Transforms&gt;
                              &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                                  &lt;ec:InclusiveNamespaces PrefixList="elc tem" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
                              &lt;/ds:Transform&gt;
                          &lt;/ds:Transforms&gt;
                          &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
                          &lt;ds:DigestValue&gt;dx3Bq2k18snVIR+CzEoyLZ3/jRc=&lt;/ds:DigestValue&gt;
                      &lt;/ds:Reference&gt;
                  &lt;/ds:SignedInfo&gt;
                  &lt;ds:SignatureValue&gt;KSvaK2EneWvtLXFMmynnBFd0h9PPnuipBa3Lib2pchGOtt8K3g8GsHAT5Vg6nGsNpo1e8SeikrNK4KRtUDne3CjvMh+LOajCpfWwl3u7W1yjp52HUODy+uZOfjL+B+9/kcDLyeJTdbB6KLVCwmD3TDuVA7tApR92VFXKTDT8X8DXrKaEl5a7fPLeb6mYfdAWsxY6Ua5KLZN+IGZAJsWi2SdOEhfHtMzbBvFOXokwysmLaYTmcY0GAkMq74Khna36SVUgxpSDDZoeDiHFGyu5CT9ClbJy8WTEAcJzlok1tvtikGzU//Md0ky0u4fuFiKeQlF+Qw/AxRG7SDqbdcLWrA==&lt;/ds:SignatureValue&gt;
                  &lt;ds:KeyInfo Id="KI-F86143B2B1BBA025BF144915430086959"&gt;
                      &lt;wsse:SecurityTokenReference wsu:Id="STR-F86143B2B1BBA025BF144915430086960"&gt;
                          &lt;wsse:Reference URI="#X509-F86143B2B1BBA025BF144915430086958" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/&gt;
                      &lt;/wsse:SecurityTokenReference&gt;
                  &lt;/ds:KeyInfo&gt;
              &lt;/ds:Signature&gt;
          &lt;/wsse:Security&gt;
      &lt;/soapenv:Header&gt;
      &lt;soapenv:Body wsu:Id="id-C412303BE3B390B3D114265182390669" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
          &lt;tem:SendMessage&gt;
              &lt;tem:request&gt;
                  &lt;elc:XmlData&gt;
                      &lt;![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;test/&gt;]]&gt;&lt;/elc:XmlData&gt;
              &lt;/tem:request&gt;
          &lt;/tem:SendMessage&gt;
      &lt;/soapenv:Body&gt;
  &lt;/soapenv:Envelope&gt;
  </code></pre>
  
  <p>You can see that there is a lot of information to put in the header, and the signature is separated from the real message to send. This is the code I have:</p>
  
  <pre><code>import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.security.cert.Certificate;
  import java.security.cert.CertificateException;
  import java.security.InvalidAlgorithmParameterException;
  import java.security.Key;
  import java.security.KeyException;
  import java.security.KeyPair;
  import java.security.KeyPairGenerator;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.PrivateKey;
  import java.security.Provider;
  import java.security.PublicKey;
  import java.security.UnrecoverableKeyException;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Enumeration;
  import java.util.List;
  
  import javax.security.cert.X509Certificate;
  import javax.xml.crypto.MarshalException;
  import javax.xml.crypto.XMLStructure;
  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.Transform;
  import javax.xml.crypto.dsig.XMLSignature;
  import javax.xml.crypto.dsig.XMLSignatureException;
  import javax.xml.crypto.dsig.XMLSignatureFactory;
  import javax.xml.crypto.dsig.dom.DOMSignContext;
  import javax.xml.crypto.dsig.keyinfo.KeyInfo;
  import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
  import javax.xml.crypto.dsig.keyinfo.KeyValue;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerConfigurationException;
  import javax.xml.transform.TransformerException;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.dom.DOMSource;
  import javax.xml.transform.stream.StreamResult;
  
  import org.w3c.dom.Document;
  import org.xml.sax.SAXException;
  
  public class Sign {
  
      public static void main(String[] args) throws 
      KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, IOException, 
      InvalidAlgorithmParameterException, InstantiationException, IllegalAccessException, ClassNotFoundException, 
      KeyException, SAXException, ParserConfigurationException, MarshalException, XMLSignatureException, TransformerException {
          String providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
          XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",(Provider) Class.forName(providerName).newInstance());
          Reference ref = fac.newReference("",fac.newDigestMethod(DigestMethod.SHA1, null),Collections.singletonList( fac.newTransform(Transform.ENVELOPED, (XMLStructure) null)),null, null);
          SignedInfo si = fac.newSignedInfo(
              fac.newCanonicalizationMethod(
                  CanonicalizationMethod.EXCLUSIVE,
                  (XMLStructure) null
              ),
              fac.newSignatureMethod(
                      SignatureMethod.RSA_SHA1, 
                      null
              ),
              Collections.singletonList(ref)
          );
  
          FileInputStream is = new FileInputStream("D:\\Step 1\\mock\\NewJKS.jks");
  
          KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
          keystore.load(is, null);
          //Enumeration&lt;String&gt; myEnum = keystore.aliases();
          for (Enumeration&lt;String&gt; e = keystore.aliases(); e.hasMoreElements();){
              System.out.println(e.nextElement());
          }               
  
          String alias = "toto";
          Key key = keystore.getKey(alias, null); 
          System.out.println(key);
          KeyPair kp = null;
          if (key instanceof PrivateKey) {
            // Get certificate of public key
            Certificate cert = keystore.getCertificate(alias);
            // Get public key
            PublicKey publicKey = cert.getPublicKey();
            // Return a key pair
            kp = new KeyPair(publicKey, (PrivateKey) key);          
  //        System.out.println(kp);
          }
  
  
          KeyInfoFactory kif = fac.getKeyInfoFactory();
          KeyValue kv = kif.newKeyValue(kp.getPublic());
          KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
  
          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
          dbf.setNamespaceAware(true);
          Document doc = dbf.newDocumentBuilder().parse(new FileInputStream("D:\\Step 1\\mock\\XMLTestData.xml"));
          DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement());
          XMLSignature signature = fac.newXMLSignature(si, ki);
          signature.sign(dsc);
          TransformerFactory tf = TransformerFactory.newInstance();
          Transformer trans = tf.newTransformer();
          trans.transform(new DOMSource(doc),new StreamResult(new FileOutputStream("D:\\Step 1\\mock\\mySignedFile2.xml")));
  
      }
  
  }
  </code></pre>
  
  <p>What I get is something like this:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
  &lt;test&gt;
      &lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;SignedInfo&gt;
              &lt;CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
              &lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
              &lt;Reference URI=""&gt;
                  &lt;Transforms&gt;
                      &lt;Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/&gt;
                  &lt;/Transforms&gt;
                  &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
                  &lt;DigestValue&gt;iUqbN+l20aP00zS0qltBAv2oDbc=&lt;/DigestValue&gt;
              &lt;/Reference&gt;
          &lt;/SignedInfo&gt;
          &lt;SignatureValue&gt;NiLEgObJbPot9kUJQ3kHi2z/1e6SGCqiZbrbAtc1snZp8MxoMothOA3dyqi6sDOBiLfdz7hRdEj+
  gMwvkxci+KaqBtK2Rv9l9eE+/X5rjJz0aQM2Dq9kxB3BFwCSLdK0uMoO7YKAr6e6QirRI70npERt
  gzAu4mriUpSkm5gbtWg=&lt;/SignatureValue&gt;
          &lt;KeyInfo&gt;
              &lt;KeyValue&gt;
                  &lt;RSAKeyValue&gt;
                      &lt;Modulus&gt;tDcB3pWauMi0lZl7U/1g6Zj2dmeaokXJkbnytLtWCC1tyPsiWGNPxlKygVF+Pm+w4jciJxDzSxex
  XY4jKTZz3a7qnq9EE/qo1ESzXpp+tus83iZFpPH+VpqBmcf1eutzSyEAqyYybAWm5p5q+2IqW+9H
  UXIjgJczkCX/5nU7M6s=&lt;/Modulus&gt;
                      &lt;Exponent&gt;AQAB&lt;/Exponent&gt;
                  &lt;/RSAKeyValue&gt;
              &lt;/KeyValue&gt;
          &lt;/KeyInfo&gt;
      &lt;/Signature&gt;
  &lt;/test&gt;
  </code></pre>
  
  <p>My first question is how can I modify my source code to have an enveloping signature?</p>