001 // Copyright (C) 2002 IAIK 002 // https://jce.iaik.tugraz.at 003 // 004 // Copyright (C) 2003 - 2025 Stiftung Secure Information and 005 // Communication Technologies SIC 006 // https://sic.tech 007 // 008 // All rights reserved. 009 // 010 // Redistribution and use in source and binary forms, with or without 011 // modification, are permitted provided that the following conditions 012 // are met: 013 // 1. Redistributions of source code must retain the above copyright 014 // notice, this list of conditions and the following disclaimer. 015 // 2. Redistributions in binary form must reproduce the above copyright 016 // notice, this list of conditions and the following disclaimer in the 017 // documentation and/or other materials provided with the distribution. 018 // 019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 020 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 021 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 023 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 024 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 025 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 026 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 027 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 028 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 029 // SUCH DAMAGE. 030 031 // Copyright (C) 2002 IAIK 032 // https://sic.tech/ 033 // 034 // Copyright (C) 2003 - 2025 Stiftung Secure Information and 035 // Communication Technologies SIC 036 // https://sic.tech/ 037 // 038 // All rights reserved. 039 // 040 // This source is provided for inspection purposes and recompilation only, 041 // unless specified differently in a contract with IAIK. This source has to 042 // be kept in strict confidence and must not be disclosed to any third party 043 // under any circumstances. Redistribution in source and binary forms, with 044 // or without modification, are <not> permitted in any case! 045 // 046 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 047 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 048 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 049 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 050 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 051 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 052 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 053 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 054 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 055 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 056 // SUCH DAMAGE. 057 // 058 // $Header: /IAIK-CMS/current/src/demo/cms/encryptedData/EncryptedDataDemo.java 17 12.02.25 17:58 Dbratko $ 059 // $Revision: 17 $ 060 // 061 062 package demo.cms.encryptedData; 063 064 import iaik.asn1.structures.AlgorithmID; 065 import iaik.cms.CMSException; 066 import iaik.cms.EncryptedContentInfo; 067 import iaik.cms.EncryptedContentInfoStream; 068 import iaik.cms.EncryptedData; 069 import iaik.cms.EncryptedDataStream; 070 import iaik.security.random.SecRandom; 071 import iaik.utils.Util; 072 073 import java.io.ByteArrayInputStream; 074 import java.io.ByteArrayOutputStream; 075 import java.io.IOException; 076 import java.io.InputStream; 077 import java.security.InvalidAlgorithmParameterException; 078 import java.security.InvalidKeyException; 079 import java.security.NoSuchAlgorithmException; 080 import java.security.SecureRandom; 081 import java.security.spec.InvalidParameterSpecException; 082 083 import demo.DemoUtil; 084 085 /** 086 * Demonstrates the usage of class {@link iaik.cms.EncryptedDataStream} and 087 * {@link iaik.cms.EncryptedData} for encrypting data using the CMS type 088 * EncryptedData. 089 */ 090 public class EncryptedDataDemo { 091 092 // secure random number generator 093 SecureRandom random; 094 095 /** 096 * Default constructor. 097 */ 098 public EncryptedDataDemo() { 099 100 System.out.println(); 101 System.out.println("**********************************************************************************"); 102 System.out.println("* EncryptedDataDemo demo *"); 103 System.out.println("* (shows the usage of the CMS EncryptedData type implementation) *"); 104 System.out.println("**********************************************************************************"); 105 System.out.println(); 106 107 random = SecRandom.getDefault(); 108 } 109 110 111 /** 112 * Creates a CMS <code>EncryptedDataStream</code> message. 113 * <p> 114 * The supplied content is PBE-encrypted using the specified password. 115 * 116 * @param message the message to be encrypted, as byte representation 117 * @param pbeAlgorithm the PBE algorithm to be used 118 * @param password the password 119 * @return the DER encoding of the <code>EncryptedData</code> object just created 120 * @throws CMSException if the <code>EncryptedData</code> object cannot 121 * be created 122 * @throws IOException if an I/O error occurs 123 */ 124 public byte[] createEncryptedDataStream(byte[] message, AlgorithmID pbeAlgorithm, char[] password) throws CMSException, IOException { 125 126 EncryptedDataStream encrypted_data; 127 128 // we are testing the stream interface 129 ByteArrayInputStream is = new ByteArrayInputStream(message); 130 // create a new EncryptedData object encrypted with TripleDES CBC 131 try { 132 encrypted_data = new EncryptedDataStream(is, 2048); 133 encrypted_data.setupCipher(pbeAlgorithm, password); 134 } catch (InvalidKeyException ex) { 135 throw new CMSException("Key error: "+ex.getMessage()); 136 } catch (NoSuchAlgorithmException ex) { 137 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 138 } 139 140 // return the EncryptedData as DER encoded byte array with block size 2048 141 ByteArrayOutputStream os = new ByteArrayOutputStream(); 142 encrypted_data.writeTo(os); 143 return os.toByteArray(); 144 } 145 146 /** 147 * Decrypts the PBE-encrypted content of the given CMS <code>EncryptedData</code> object 148 * using the specified password and returns the decrypted (= original) message. 149 * 150 * @param encoding the <code>EncryptedData</code> object as DER encoded byte array 151 * @param password the password to decrypt the message 152 * 153 * @return the recovered message, as byte array 154 * @throws CMSException if the message cannot be recovered 155 * @throws IOException if an I/O error occurs 156 */ 157 public byte[] getEncryptedDataStream(byte[] encoding, char[] password) throws CMSException, IOException { 158 159 // create the EncryptpedData object from a DER encoded byte array 160 // we are testing the stream interface 161 ByteArrayInputStream is = new ByteArrayInputStream(encoding); 162 EncryptedDataStream encrypted_data = new EncryptedDataStream(is); 163 164 System.out.println("Information about the encrypted data:"); 165 EncryptedContentInfoStream eci = encrypted_data.getEncryptedContentInfo(); 166 System.out.println("Content type: "+eci.getContentType().getName()); 167 System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName()); 168 169 // decrypt the message 170 try { 171 encrypted_data.setupCipher(password); 172 InputStream decrypted = encrypted_data.getInputStream(); 173 ByteArrayOutputStream os = new ByteArrayOutputStream(); 174 Util.copyStream(decrypted, os, null); 175 176 return os.toByteArray(); 177 178 } catch (InvalidKeyException ex) { 179 throw new CMSException("Key error: "+ex.getMessage()); 180 } catch (NoSuchAlgorithmException ex) { 181 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 182 } catch (InvalidAlgorithmParameterException ex) { 183 throw new CMSException("Invalid Parameters: "+ex.getMessage()); 184 } catch (InvalidParameterSpecException ex) { 185 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 186 } 187 } 188 189 /** 190 * Creates a CMS <code>EncryptedData</code> message. 191 * <p> 192 * The supplied content is PBE-encrypted using the specified password. 193 * 194 * @param message the message to be encrypted, as byte representation 195 * @param pbeAlgorithm the PBE algorithm to be used 196 * @param password the password 197 * @return the DER encoding of the <code>EncryptedData</code> object just created 198 * @throws CMSException if the <code>EncryptedData</code> object cannot 199 * be created 200 * @throws IOException if an I/O error occurs 201 */ 202 public byte[] createEncryptedData(byte[] message, AlgorithmID pbeAlgorithm, char[] password) throws CMSException, IOException { 203 204 EncryptedData encrypted_data; 205 206 try { 207 encrypted_data = new EncryptedData(message); 208 // encrypt the message 209 encrypted_data.setupCipher(pbeAlgorithm, password); 210 } catch (InvalidKeyException ex) { 211 throw new CMSException("Key error: "+ex.getMessage()); 212 } catch (NoSuchAlgorithmException ex) { 213 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 214 } 215 return encrypted_data.getEncoded(); 216 217 } 218 219 /** 220 * Decrypts the PBE-encrypted content of the given CMS <code>EncryptedData</code> object 221 * using the specified password and returns the decrypted (= original) message. 222 * 223 * @param encoding the DER encoded <code>EncryptedData</code> object 224 * @param password the password to decrypt the message 225 * 226 * @return the recovered message, as byte array 227 * @throws CMSException if the message cannot be recovered 228 * @throws IOException if an I/O error occurs 229 */ 230 public byte[] getEncryptedData(byte[] encoding, char[] password) throws CMSException, IOException { 231 232 // create an EncryptedData from the ASN1Object 233 EncryptedData encrypted_data = new EncryptedData(new ByteArrayInputStream(encoding)); 234 235 System.out.println("Information about the encrypted data:"); 236 EncryptedContentInfo eci = (EncryptedContentInfo)encrypted_data.getEncryptedContentInfo(); 237 System.out.println("Content type: "+eci.getContentType().getName()); 238 System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName()); 239 240 // decrypt the message 241 try { 242 encrypted_data.setupCipher(password); 243 return encrypted_data.getContent(); 244 245 } catch (InvalidKeyException ex) { 246 throw new CMSException("Key error: "+ex.getMessage()); 247 } catch (NoSuchAlgorithmException ex) { 248 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 249 } catch (InvalidAlgorithmParameterException ex) { 250 throw new CMSException("Invalid Parameters: "+ex.getMessage()); 251 } catch (InvalidParameterSpecException ex) { 252 throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage()); 253 } 254 } 255 256 257 /** 258 * Starts the tests. 259 */ 260 public void start() { 261 // the test message 262 String m = "This is the test message."; 263 System.out.println("Test message: \""+m+"\""); 264 System.out.println(); 265 byte[] message = m.getBytes(); 266 267 try { 268 byte[] encoding; 269 byte[] received_message = null; 270 System.out.println("Stream implementation demos"); 271 System.out.println("==========================="); 272 273 274 // 275 // test CMS EncryptedDataStream 276 // 277 System.out.println("\nEncryptedDataStream demo [create]:\n"); 278 encoding = createEncryptedDataStream(message, (AlgorithmID)AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.clone(), "password".toCharArray()); 279 // transmit data 280 System.out.println("\nEncryptedDataStream demo [parse]:\n"); 281 received_message = getEncryptedDataStream(encoding, "password".toCharArray()); 282 System.out.print("\nContent: "); 283 System.out.println(new String(received_message)); 284 285 286 287 // the non-stream implementation 288 System.out.println("\nNon-stream implementation demos"); 289 System.out.println("==============================="); 290 291 // 292 // test CMS EncryptedData 293 // 294 System.out.println("\nEncryptedData demo [create]:\n"); 295 encoding = createEncryptedData(message, (AlgorithmID)AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.clone(), "password".toCharArray()); 296 // transmit data 297 System.out.println("\nEncryptedData demo [parse]:\n"); 298 received_message = getEncryptedData(encoding, "password".toCharArray()); 299 System.out.print("\nContent: "); 300 System.out.println(new String(received_message)); 301 302 } catch (Exception ex) { 303 ex.printStackTrace(); 304 throw new RuntimeException(ex.toString()); 305 } 306 } 307 308 /** 309 * Maim method. 310 */ 311 public static void main(String argv[]) throws Exception { 312 313 DemoUtil.initDemos(); 314 315 (new EncryptedDataDemo()).start(); 316 System.out.println("\nReady!"); 317 DemoUtil.waitKey(); 318 } 319 }