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 }