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