1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 package javax.xml.crypto.dsig.samples;
20 
21 import javax.xml.crypto.*;
22 import javax.xml.crypto.dsig.*;
23 import javax.xml.crypto.dom.*;
24 import javax.xml.crypto.dsig.dom.DOMSignContext;
25 import javax.xml.crypto.dsig.keyinfo.*;
26 import javax.xml.crypto.dsig.spec.*;
27 import java.io.FileInputStream;
28 import java.io.FileOutputStream;
29 import java.io.OutputStream;
30 import java.security.*;
31 import java.util.Collections;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.transform.*;
34 import javax.xml.transform.dom.DOMSource;
35 import javax.xml.transform.stream.StreamResult;
36 import org.w3c.dom.Document;
37 
38 /**
39  * This is a simple example of generating an Enveloped XML
40  * Signature using the JSR 105 API. The resulting signature will look
41  * like (key and signature values will be different):
42  *
43  * <pre><code>
44  *<Envelope xmlns="urn:envelope">
45  * <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
46  *   <SignedInfo>
47  *     <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n
48 -20010315"/>
49  *     <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
50  *     <Reference URI="">
51  *       <Transforms>
52  *         <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
53  *       </Transforms>
54  *       <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
55  *       <DigestValue>K8M/lPbKnuMDsO0Uzuj75lQtzQI=<DigestValue>
56  *     </Reference>
57  *   </SignedInfo>
58  *   <SignatureValue>
59  *     DpEylhQoiUKBoKWmYfajXO7LZxiDYgVtUtCNyTgwZgoChzorA2nhkQ==
60  *   </SignatureValue>
61  *   <KeyInfo>
62  *     <KeyValue>
63  *       <DSAKeyValue>
64  *         <P>
65  *           rFto8uPQM6y34FLPmDh40BLJ1rVrC8VeRquuhPZ6jYNFkQuwxnu/wCvIAMhukPBL
66  *           FET8bJf/b2ef+oqxZajEb+88zlZoyG8g/wMfDBHTxz+CnowLahnCCTYBp5kt7G8q
67  *           UobJuvjylwj1st7V9Lsu03iXMXtbiriUjFa5gURasN8=
68  *         </P>
69  *         <Q>
70  *           kEjAFpCe4lcUOdwphpzf+tBaUds=
71  *         </Q>
72  *         <G>
73  *           oe14R2OtyKx+s+60O5BRNMOYpIg2TU/f15N3bsDErKOWtKXeNK9FS7dWStreDxo2
74  *           SSgOonqAd4FuJ/4uva7GgNL4ULIqY7E+mW5iwJ7n/WTELh98mEocsLXkNh24HcH4
75  *           BZfSCTruuzmCyjdV1KSqX/Eux04HfCWYmdxN3SQ/qqw=
76  *         </G>
77  *         <Y>
78  *           pA5NnZvcd574WRXuOA7ZfC/7Lqt4cB0MRLWtHubtJoVOao9ib5ry4rTk0r6ddnOv
79  *           AIGKktutzK3ymvKleS3DOrwZQgJ+/BDWDW8kO9R66o6rdjiSobBi/0c2V1+dkqOg
80  *           jFmKz395mvCOZGhC7fqAVhHat2EjGPMfgSZyABa7+1k=
81  *         </Y>
82  *       </DSAKeyValue>
83  *     </KeyValue>
84  *   </KeyInfo>
85  * </Signature>
86  *</Envelope>
87  * </code></pre>
88  */
89 public class GenEnveloped {
90 
91     //
92     // Synopsis: java GenEnveloped [document] [output]
93     //
94     //    where "document" is the name of a file containing the XML document
95     //    to be signed, and "output" is the name of the file to store the
96     //    signed document. The 2nd argument is optional - if not specified,
97     //    standard output will be used.
98     //
main(String[] args)99     public static void main(String[] args) throws Exception {
100 
101         // Create a DOM XMLSignatureFactory that will be used to generate the
102         // enveloped signature
103         String providerName = System.getProperty
104             ("jsr105Provider", "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI");
105         XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
106              (Provider) Class.forName(providerName).newInstance());
107 
108         // Create a Reference to the enveloped document (in this case we are
109         // signing the whole document, so a URI of "" signifies that) and
110         // also specify the SHA1 digest algorithm and the ENVELOPED Transform.
111         Reference ref = fac.newReference
112             ("", fac.newDigestMethod(DigestMethod.SHA1, null),
113              Collections.singletonList
114               (fac.newTransform
115                 (Transform.ENVELOPED, (TransformParameterSpec) null)),
116              null, null);
117 
118         // Create the SignedInfo
119         SignedInfo si = fac.newSignedInfo
120             (fac.newCanonicalizationMethod
121              (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
122               (C14NMethodParameterSpec) null),
123              fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
124              Collections.singletonList(ref));
125 
126         // Create a DSA KeyPair
127         KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
128         kpg.initialize(512);
129         KeyPair kp = kpg.generateKeyPair();
130 
131         // Create a KeyValue containing the DSA PublicKey that was generated
132         KeyInfoFactory kif = fac.getKeyInfoFactory();
133         KeyValue kv = kif.newKeyValue(kp.getPublic());
134 
135         // Create a KeyInfo and add the KeyValue to it
136         KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
137 
138         // Instantiate the document to be signed
139         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
140         dbf.setNamespaceAware(true);
141         Document doc =
142             dbf.newDocumentBuilder().parse(new FileInputStream(args[0]));
143 
144         // Create a DOMSignContext and specify the DSA PrivateKey and
145         // location of the resulting XMLSignature's parent element
146         DOMSignContext dsc = new DOMSignContext
147             (kp.getPrivate(), doc.getDocumentElement());
148 
149         // Create the XMLSignature (but don't sign it yet)
150         XMLSignature signature = fac.newXMLSignature(si, ki);
151 
152         // Marshal, generate (and sign) the enveloped signature
153         signature.sign(dsc);
154 
155         // output the resulting document
156         OutputStream os;
157         if (args.length > 1) {
158            os = new FileOutputStream(args[1]);
159         } else {
160            os = System.out;
161         }
162 
163         TransformerFactory tf = TransformerFactory.newInstance();
164         Transformer trans = tf.newTransformer();
165         trans.transform(new DOMSource(doc), new StreamResult(os));
166     }
167 }
168