No Doubt! Apache’s XML Security will encrypt subtrees!

Posted by Payne on June 23rd, 2006

Original post 10 May 2004. TODO: Still need to update the before and
after samples…

It was easy to hack the org.apache.xml.security.samples.encryption.Encrypter
demo to show that just a subtree of a document could be encrypted….
before
after

  1  /*
  2   * Copyright  1999-2004 The Apache Software Foundation.
  3   *
  4   *  Licensed under the Apache License, Version 2.0 (the "License");
  5   *  you may not use this file except in compliance with the License.
  6   *  You may obtain a copy of the License at
  7   *
  8   *      http://www.apache.org/licenses/LICENSE-2.0
  9   *
 10   *  Unless required by applicable law or agreed to in writing, software
 11   *  distributed under the License is distributed on an "AS IS" BASIS,
 12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13   *  See the License for the specific language governing permissions and
 14   *  limitations under the License.
 15   *
 16   */
 17  package org.apache.xml.security.samples.encryption;
 18
 19
 20  import java.io.File;
 21  import java.io.FileInputStream;
 22  import java.io.FileOutputStream;
 23
 24  import java.security.Key;
 25
 26  import javax.crypto.SecretKey;
 27  import javax.crypto.KeyGenerator;
 28
 29  import org.apache.xml.security.keys.KeyInfo;
 30  import org.apache.xml.security.encryption.XMLCipher;
 31  import org.apache.xml.security.encryption.EncryptedData;
 32  import org.apache.xml.security.encryption.EncryptedKey;
 33  import org.apache.xml.security.utils.XMLUtils;
 34  import org.apache.xml.security.utils.Constants;
 35
 36  import org.w3c.dom.Document;
 37  import org.w3c.dom.Element;
 38  import org.w3c.dom.NodeList;
 39
 40  import javax.xml.transform.TransformerFactory;
 41  import javax.xml.transform.Transformer;
 42  import javax.xml.transform.dom.DOMSource;
 43  import javax.xml.transform.stream.StreamResult;
 44  import javax.xml.transform.OutputKeys;
 45
 46  /**
 47   * This sample demonstrates how to encrypt data inside an xml document.
 48   *
 49   * @author Vishal Mahajan (Sun Microsystems)
 50   * Hacked by Matt
 51   */
 52  public class Encrypter2 {
 53
 54      /** {@link org.apache.commons.logging} logging facility */
 55      static org.apache.commons.logging.Log log =
 56          org.apache.commons.logging.LogFactory.getLog(
 57              Encrypter2.class.getName());
 58
 59      static {
 60          org.apache.xml.security.Init.init();
 61      }
 62
 63      private static Document createSampleDocument() throws Exception {
 64
 65          javax.xml.parsers.DocumentBuilderFactory dbf =
 66              javax.xml.parsers.DocumentBuilderFactory.newInstance();
 67          dbf.setNamespaceAware(true);
 68          javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
 69          Document document = db.newDocument();
 70
 71          /**
 72           * Build a sample document. It will look something like:
 73           *
 74           * <apache:RootElement xmlns:apache="http://www.apache.org/ns/#app1">
 75           * <apache:foo>Some simple text</apache:foo>
 76           * </apache:RootElement>
 77           */
 78          Element root =
 79              document.createElementNS(
 80                  "http://www.apache.org/ns/#app1", "apache:RootElement");
 81          root.setAttributeNS(
 82              Constants.NamespaceSpecNS,
 83              "xmlns:apache",
 84              "http://www.apache.org/ns/#app1");
 85          document.appendChild(root);
 86
 87          root.appendChild(document.createTextNode("\n"));
 88
 89          Element childElement =
 90              document.createElementNS(
 91                  "http://www.apache.org/ns/#app1", "apache:foo");
 92          childElement.appendChild(
 93              document.createTextNode("Some simple text"));
 94
 95          Element e2 = document.createElementNS(
 96                  "http://www.apache.org/ns/#app1", "apache:goo");
 97                  e2.appendChild(document.createTextNode("Weather Report"));
 98
 99                  Element e3 = document.createElementNS(
100                  "http://www.apache.org/ns/#app1", "apache:bar");
101                  e3.appendChild(document.createTextNode("No Doubt"));
102
103                  e2.appendChild(e3);
104
105                  e2.appendChild( e3.appendChild(document.createTextNode("biteme")));
106
107          childElement.appendChild(e2);
108
109
110          root.appendChild(childElement);
111
112          root.appendChild(document.createTextNode("\n"));
113
114
115          outputDocToFile(document, "before2.xml");
116
117          return document;
118      }
119
120      private static SecretKey GenerateAndStoreKeyEncryptionKey()
121          throws Exception {
122
123          String jceAlgorithmName = "DESede";
124          KeyGenerator keyGenerator =
125              KeyGenerator.getInstance(jceAlgorithmName);
126          SecretKey kek = keyGenerator.generateKey();
127
128          byte[] keyBytes = kek.getEncoded();
129          File kekFile = new File("kek");
130          FileOutputStream f = new FileOutputStream(kekFile);
131          f.write(keyBytes);
132          f.close();
133          System.out.println(
134              "Key encryption key stored in " + kekFile.toURL().toString());
135
136          return kek;
137      }
138
139      private static SecretKey GenerateDataEncryptionKey() throws Exception {
140
141          String jceAlgorithmName = "AES";
142          KeyGenerator keyGenerator =
143              KeyGenerator.getInstance(jceAlgorithmName);
144          keyGenerator.init(128);
145          return keyGenerator.generateKey();
146      }
147
148      private static void outputDocToFile(Document doc, String fileName)
149          throws Exception {
150          File encryptionFile = new File(fileName);
151          FileOutputStream f = new FileOutputStream(encryptionFile);
152
153          TransformerFactory factory = TransformerFactory.newInstance();
154          Transformer transformer = factory.newTransformer();
155          transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
156          DOMSource source = new DOMSource(doc);
157          StreamResult result = new StreamResult(f);
158          transformer.transform(source, result);
159
160          f.close();
161          System.out.println(
162              "Wrote document containing encrypted data to " +
163              encryptionFile.toURL().toString());
164      }
165
166      public static void main(String unused[]) throws Exception {
167
168          Document document = createSampleDocument();
169
170          /*
171           * Get a key to be used for encrypting the element.
172           * Here we are generating an AES key.
173           */
174          Key symmetricKey = GenerateDataEncryptionKey();
175
176          /*
177           * Get a key to be used for encrypting the symmetric key.
178           * Here we are generating a DESede key.
179           */
180          Key kek = GenerateAndStoreKeyEncryptionKey();
181
182          String algorithmURI = XMLCipher.TRIPLEDES_KeyWrap;
183
184          XMLCipher keyCipher =
185              XMLCipher.getInstance(algorithmURI);
186          keyCipher.init(XMLCipher.WRAP_MODE, kek);
187          EncryptedKey encryptedKey =
188              keyCipher.encryptKey(document, symmetricKey);
189
190          /*
191           * Let us encrypt the contents of the document element.
192           */
193          Element rootElement = document.getDocumentElement();
194          NodeList node =  rootElement.getElementsByTagName("apache:bar");
195          rootElement = (Element) node.item(0);
196          System.out.println("node="+node);
197         // rootElement = (Element)
198                  System.out.println("rootElement="+rootElement);
199          //rootElement = (Element) rootElement.getFirstChild().getFirstChild();
200
201          algorithmURI = XMLCipher.AES_128;
202
203          XMLCipher xmlCipher =
204              XMLCipher.getInstance(algorithmURI);
205          xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetricKey);
206
207          /*
208           * Setting keyinfo inside the encrypted data being prepared.
209           */
210          EncryptedData encryptedData = xmlCipher.getEncryptedData();
211          KeyInfo keyInfo = new KeyInfo(document);
212          keyInfo.add(encryptedKey);
213          encryptedData.setKeyInfo(keyInfo);
214
215          /*
216           * doFinal -
217           * "true" below indicates that we want to encrypt element's content
218           * and not the element itself. Also, the doFinal method would
219           * modify the document by replacing the EncrypteData element
220           * for the data to be encrypted.
221           */
222          xmlCipher.doFinal(document, rootElement, true);
223
224          /*
225           * Output the document containing the encrypted information into
226           * a file.
227           */
228          outputDocToFile(document, "encryptedInfo2.xml");
229      }
230  }

POST INFO: This entry http://www.mattpayne.org/blog/2006/06/23/no-doubt-apaches-xml-security-will-encrypt-subtrees/ was posted on Friday, June 23rd, 2006 at 4:55 pm and is filed under Crypto, Java. .

Responses are currently closed, but you can trackback from your own site.