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.