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/pkcs7cms/PKCS7CMSEncryptedContentInfoDemo.java 25 12.02.25 17:58 Dbratko $ 029// $Revision: 25 $ 030// 031 032package demo.cms.pkcs7cms; 033 034import iaik.asn1.ASN; 035import iaik.asn1.ASN1Object; 036import iaik.asn1.INTEGER; 037import iaik.asn1.OCTET_STRING; 038import iaik.asn1.ObjectID; 039import iaik.asn1.SEQUENCE; 040import iaik.asn1.structures.AlgorithmID; 041import iaik.cms.EncryptedContentInfoStream; 042import iaik.cms.EnvelopedDataStream; 043import iaik.cms.KeyTransRecipientInfo; 044import iaik.cms.RecipientInfo; 045import iaik.cms.SecurityProvider; 046import iaik.security.random.SecRandom; 047import iaik.utils.Util; 048import iaik.x509.X509Certificate; 049 050import java.io.ByteArrayInputStream; 051import java.io.ByteArrayOutputStream; 052import java.io.IOException; 053import java.io.InputStream; 054import java.math.BigInteger; 055import java.security.PrivateKey; 056import java.security.SecureRandom; 057import java.security.spec.AlgorithmParameterSpec; 058 059import javax.crypto.KeyGenerator; 060import javax.crypto.SecretKey; 061import javax.crypto.spec.IvParameterSpec; 062import javax.crypto.spec.RC2ParameterSpec; 063 064import demo.DemoUtil; 065import demo.keystore.CMSKeyStore; 066 067/** 068 * This class demonstrates the EnvelopedDataStream/EncryptedContentInfoStream usages 069 * for algorithms that may require a specific parameter handling. 070 * <p> 071 * This class shows the compatibility to PKCS#7. 072 * <p> 073 * All keys and certificates are read from a keystore created by the 074 * SetupCMSKeyStore program. 075 * <p> 076 * The following algorithms are demonstrated: 077 * <ul> 078 * <li>ARCFOUR: Variable-key-size stream cipher; no parameters to be sent 079 * <li>RC2_CBC: Variable-key-size block cipher; parameters as used by S/MIME: 080 * rc2ParamterVersion and IV; encoded as SEQUENCE: 081 * <pre> 082 * RC2-CBC parameter ::= SEQUENCE { 083 * rc2ParameterVersion INTEGER, 084 * iv OCTET STRING (8)} 085 * 086 * For the effective-key-bits of 40, 64, and 128, the 087 * rc2ParameterVersion values are 160, 120, 58 respectively. 088 * </pre> 089 * <li>CAST5_CBC: Feistel type block cipher with key sizes of 40-128 bit in 8 bit 090 * increments; parameters (RFC 2144): 091 * <pre> 092 * Parameters ::= SEQUENCE { 093 * iv OCTET STRING DEFAULT 0, 094 * keyLength INTEGER } 095 * 096 * </pre> 097 * </ul> 098 * This class shows how an EncryptedContentInfo is explicit created for encrypt�ng 099 * the content and supplying it to an EnvelopedDataStream object. Note that IAIK-CMS 100 * also allows to use EnvelopedData(Stream) for algorithms like RC2, ARCFOUR or CAST in 101 * without having the necessity of explicit key/parameter handling, see {@link 102 * demo.cms.envelopedData.RC2EnvelopedDataDemo RC2EnvelopedDataDemo} for an example. 103 * <p> 104 * Note that the usage of algorithms like RC2 is deprecated but used here for this 105 * demo since it requires a specific parameter handling. 106 */ 107public class PKCS7CMSEncryptedContentInfoDemo { 108 109 // certificate of user 1 110 X509Certificate user1; 111 // private key of user 1 112 PrivateKey user1_pk; 113 // certificate of user 2 114 X509Certificate user2; 115 // private key of user 2 116 PrivateKey user2_pk; 117 // secure random number generator 118 SecureRandom random; 119 120 /** 121 * Setup the demo certificate chains. 122 * 123 * Keys and certificate are retrieved from the demo KeyStore. 124 * 125 * @throws IOException if an file read error occurs 126 */ 127 public PKCS7CMSEncryptedContentInfoDemo() throws IOException { 128 129 System.out.println(); 130 System.out.println("********************************************************************************************************"); 131 System.out.println("* PKCS7CMSEncryptedContentInfoDemo *"); 132 System.out.println("* (tests the CMS EncryptedContentInfo against the IAIK-JCE PKCS#7 EncryptedContentInfo implementation) *"); 133 System.out.println("********************************************************************************************************"); 134 System.out.println(); 135 136 // add all certificates to the list 137 X509Certificate[] certs = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1); 138 user1 = certs[0]; 139 user1_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1); 140 user2 = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0]; 141 user2_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2); 142 143 random = SecRandom.getDefault(); 144 145 146 147 } 148 149 150 /** 151 * Creates a CMS <code>EnvelopedDataStream</code> message. 152 * 153 * @param message the message to be enveloped, as byte representation 154 * @param contentEA the content encryption algorithm 155 * @param keyLength the key length for the symmetric key 156 * @return the DER encoding of the <code>EnvelopedData</code> object just created 157 * @throws Exception if the <code>EnvelopedData</code> object cannot be created 158 */ 159 public byte[] createEnvelopedDataStream(byte[] message, AlgorithmID contentEA, int keyLength) throws Exception { 160 161 SecurityProvider provider = SecurityProvider.getSecurityProvider(); 162 ByteArrayInputStream is = new ByteArrayInputStream(message); 163 164 AlgorithmParameterSpec params = null; 165 SecretKey secretKey = null; 166 167 // create iv 168 byte[] iv = new byte[8]; 169 random.nextBytes(iv); 170 171 int rc2_param = 58; 172 if (contentEA.equals(AlgorithmID.rc2_CBC)) { 173 174 switch (keyLength) { 175 case 40: 176 rc2_param = 160; 177 break; 178 case 64: 179 rc2_param = 120; 180 break; 181 default: // 128 182 rc2_param = 58; 183 keyLength = 128; 184 } 185 // create the paramters (SEQUENCE) to be sent 186 SEQUENCE parameter = new SEQUENCE(); 187 parameter.addComponent(new INTEGER(rc2_param)); 188 parameter.addComponent(new OCTET_STRING(iv)); 189 contentEA.setParameter(parameter); 190 params = new RC2ParameterSpec(keyLength,iv); 191 } else if (contentEA.equals(AlgorithmID.arcfour)){ 192 // no params for ARCFOUR 193 params = null; 194 } else if (contentEA.equals(AlgorithmID.cast5_CBC)) { 195 SEQUENCE parameter = new SEQUENCE(); 196 parameter.addComponent(new OCTET_STRING(iv)); 197 parameter.addComponent(new INTEGER(keyLength)); 198 contentEA.setParameter(parameter); 199 params = new IvParameterSpec(iv); 200 201 } else { 202 throw new Exception("Algorithm " + contentEA + " not supportted for this test!"); 203 } 204 205 KeyGenerator keyGen = provider.getKeyGenerator(contentEA, keyLength); 206 // generate a new key 207 secretKey = keyGen.generateKey(); 208 209 // create the EncryptedContentInfo for the content to be encrypted 210 EncryptedContentInfoStream eci = new EncryptedContentInfoStream(ObjectID.pkcs7_data, is); 211 // setup the cipher for encryption 212 eci.setupCipher(contentEA, secretKey, params); 213 214 // create the recipient infos 215 RecipientInfo[] recipients = new RecipientInfo[2]; 216 // user1 is the first receiver 217 recipients[0] = new KeyTransRecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 218 // encrypt the secret key for recipient 1 219 recipients[0].encryptKey(secretKey); 220 // user2 is the second receiver 221 recipients[1] = new KeyTransRecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 222 // encrypt the secret key for recipient 2 223 recipients[1].encryptKey(secretKey); 224 // now create the EnvelopedDataStream 225 EnvelopedDataStream enveloped_data = new EnvelopedDataStream(recipients, eci); 226 227 // return the EnvelopedDate as DER encoded byte array with block size 2048 228 ByteArrayOutputStream os = new ByteArrayOutputStream(); 229 enveloped_data.writeTo(os, 2048); 230 byte[] enc = os.toByteArray(); 231 return enc; 232 233 } 234 235 /** 236 * Decrypts the encrypted content of the given CMS <code>EnvelopedData</code> object for the 237 * specified recipient and returns the decrypted (= original) message. 238 * 239 * @param encoding the <code>EnvelopedData</code> object as DER encoded byte array 240 * @param privateKey the private key to decrypt the message 241 * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array 242 * to which the specified private key belongs 243 * 244 * @return the recovered message, as byte array 245 * @throws Exception if the message cannot be recovered 246 */ 247 public byte[] getEnvelopedDataStream(byte[] encoding, PrivateKey privateKey, int recipientInfoIndex) throws Exception { 248 249 // create the EnvelopedData object from a DER encoded byte array 250 // we are testing the stream interface 251 ByteArrayInputStream is = new ByteArrayInputStream(encoding); 252 EnvelopedDataStream enveloped_data = new EnvelopedDataStream(is); 253 254 AlgorithmParameterSpec params = null; 255 // get the recipient infos 256 RecipientInfo[] recipients = enveloped_data.getRecipientInfos(); 257 258 System.out.println("\nThis message can be decrypted by the owners of the following certificates:"); 259 260 for (int i=0; i<recipients.length; i++) { 261 System.out.println("Recipient "+(i+1)+":"); 262 System.out.println(recipients[i].getRecipientIdentifiers()[0]); 263 } 264 // decrypt symmetric content encryption key, e.g.: 265 SecretKey secretKey = recipients[recipientInfoIndex].decryptKey(user1_pk); 266 267 //get the ECI from the enveloped data: 268 EncryptedContentInfoStream eci = (EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo(); 269 //get the content encryption algorithm: 270 AlgorithmID contentEA = eci.getContentEncryptionAlgorithm(); 271 System.out.println("Content Encryption Algorithm: " + contentEA); 272 if (contentEA.equals(AlgorithmID.rc2_CBC)) { 273 // get the parameters as SEQUENCE 274 SEQUENCE seq = (SEQUENCE)contentEA.getParameter(); 275 // the iv is the second component 276 OCTET_STRING oct = (OCTET_STRING)seq.getComponentAt(1); 277 // create an IvParameterSpec: 278 //params = new IvParameterSpec((byte[])oct.getValue()); 279 int rc2ParameterVersion = ((BigInteger)seq.getComponentAt(0).getValue()).intValue(); 280 int effective_key_bits = 32; 281 switch (rc2ParameterVersion) { 282 case 160: 283 effective_key_bits = 40; 284 break; 285 case 120: 286 effective_key_bits = 64; 287 break; 288 case 58: 289 effective_key_bits = 128; 290 break; 291 default: 292 throw new Exception("Invalid rc2ParameterVersion " + rc2ParameterVersion + "!"); 293 294 } 295 params = new RC2ParameterSpec(effective_key_bits,(byte[])seq.getComponentAt(1).getValue()); 296 297 } 298 else if (contentEA.equals(AlgorithmID.rc5_CBC)) { 299 OCTET_STRING oct = (OCTET_STRING)contentEA.getParameter(); 300 // create an IvParameterSpec: 301 params = new IvParameterSpec((byte[])oct.getValue()); 302 } else if (contentEA.equals(AlgorithmID.arcfour)) { 303 params = null; 304 } else if (contentEA.equals(AlgorithmID.cast5_CBC)) { 305 // get the parameters 306 ASN1Object asn1Params = contentEA.getParameter(); 307 if (asn1Params.isA(ASN.SEQUENCE)) { 308 // the iv is the first component 309 params = new IvParameterSpec((byte[])asn1Params.getComponentAt(0).getValue()); 310 } else { 311 // to be compatible with (invalid) CAST AlgorithmIDs only using the IV as parameters 312 params = new IvParameterSpec((byte[])asn1Params.getValue()); 313 } 314 } else { 315 throw new Exception("Algorithm " + contentEA + " not supportted for this test!"); 316 } 317 318 319 //now setup the cipher with previously decrypted recipient key amd params 320 eci.setupCipher(secretKey, params); 321 //get and read the data thereby actually performing the decryption 322 InputStream data_is = eci.getInputStream(); 323 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 324 Util.copyStream(data_is, baos, null); 325 byte[] decrypted = baos.toByteArray(); 326 return decrypted; 327 328 } 329 330 // PKCS#7 331 332 333 /** 334 * Creates a PKCS#7 <code>EnvelopedDataStream</code> message. 335 * <p> 336 * The enveloped-data content type consists of encrypted content of any 337 * type and encrypted content-encryption keys for one or more recipients. 338 * The combination of encrypted content and encrypted content-encryption 339 * key for a recipient is a "digital envelope" for that recipient. Any type 340 * of content can be enveloped for any number of recipients in parallel. 341 * 342 * @param message the message to be enveloped, as byte representation 343 * @param cea the content encryption algorithm 344 * @param keyLength the key length for the symmetric key 345 * @return the DER encoding of the <code>EnvelopedData</code> object just created 346 * @throws Exception if the <code>EnvelopedData</code> object cannot 347 * be created 348 */ 349 public byte[] createPKCS7EnvelopedDataStream(byte[] message, AlgorithmID cea, int keyLength) throws Exception { 350 351 SecurityProvider provider = SecurityProvider.getSecurityProvider(); 352 ByteArrayInputStream is = new ByteArrayInputStream(message); 353 AlgorithmID contentEA = (AlgorithmID)cea.clone(); 354 AlgorithmParameterSpec params = null; 355 KeyGenerator key_gen = null; 356 SecretKey secretKey = null; 357 358 // create iv 359 byte[] iv = new byte[8]; 360 random.nextBytes(iv); 361 362 int rc2_param = 58; 363 if (contentEA.equals(AlgorithmID.rc2_CBC)) { 364 switch (keyLength) { 365 case 40: 366 rc2_param = 160; 367 break; 368 case 64: 369 rc2_param = 120; 370 break; 371 default: // 128 372 rc2_param = 58; 373 keyLength = 128; 374 } 375 // create the paramters (SEQUENCE) to be sent 376 SEQUENCE parameter = new SEQUENCE(); 377 parameter.addComponent(new INTEGER(rc2_param)); 378 parameter.addComponent(new OCTET_STRING(iv)); 379 contentEA.setParameter(parameter); 380 params = new RC2ParameterSpec(keyLength,iv); 381 } else if (contentEA.equals(AlgorithmID.arcfour)){ 382 // no params for ARCFOUR 383 params = null; 384 } else if (contentEA.equals(AlgorithmID.cast5_CBC)) { 385 386 SEQUENCE parameter = new SEQUENCE(); 387 parameter.addComponent(new OCTET_STRING(iv)); 388 parameter.addComponent(new INTEGER(keyLength)); 389 contentEA.setParameter(parameter); 390 params = new IvParameterSpec(iv); 391 392 } else { 393 throw new Exception("Algorithm " + contentEA + " not supportted for this test!"); 394 } 395 396 KeyGenerator keyGen = provider.getKeyGenerator(contentEA, keyLength); 397 // generate a new key 398 secretKey = keyGen.generateKey(); 399 400 // create the EncryptedContentInfo for the content to be encrypted 401 iaik.pkcs.pkcs7.EncryptedContentInfoStream eci = new iaik.pkcs.pkcs7.EncryptedContentInfoStream(ObjectID.pkcs7_data, is); 402 // setup the cipher for encryption 403 eci.setupCipher(contentEA, secretKey, params); 404 405 // create the recipient infos 406 iaik.pkcs.pkcs7.RecipientInfo[] recipients = new iaik.pkcs.pkcs7.RecipientInfo[2]; 407 // user1 is the first receiver 408 recipients[0] = new iaik.pkcs.pkcs7.RecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 409 // encrypt the secret key for recipient 1 410 recipients[0].encryptKey(secretKey); 411 // user2 is the second receiver 412 recipients[1] = new iaik.pkcs.pkcs7.RecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 413 // encrypt the secret key for recipient 2 414 recipients[1].encryptKey(secretKey); 415 // now create the EnvelopedDataStream 416 iaik.pkcs.pkcs7.EnvelopedDataStream enveloped_data = 417 new iaik.pkcs.pkcs7.EnvelopedDataStream(recipients, eci); 418 419 // return the EnvelopedDate as DER encoded byte array with block size 2048 420 ByteArrayOutputStream os = new ByteArrayOutputStream(); 421 enveloped_data.writeTo(os, 2048); 422 byte[] enc = os.toByteArray(); 423 return enc; 424 425 } 426 427 /** 428 * Decrypts the encrypted content of the given PKCS#7 <code>EnvelopedData</code> object for the 429 * specified recipient and returns the decrypted (= original) message. 430 * 431 * @param encoding the <code>EnvelopedData</code> object as DER encoded byte array 432 * @param privateKey the private key to decrypt the message 433 * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array 434 * to which the specified private key belongs 435 * 436 * @return the recovered message, as byte array 437 * @throws Exception if the message cannot be recovered 438 */ 439 public byte[] getPKCS7EnvelopedDataStream(byte[] encoding, PrivateKey privateKey, int recipientInfoIndex) throws Exception { 440 441 // create the EnvelopedData object from a DER encoded byte array 442 // we are testing the stream interface 443 ByteArrayInputStream is = new ByteArrayInputStream(encoding); 444 iaik.pkcs.pkcs7.EnvelopedDataStream enveloped_data = new iaik.pkcs.pkcs7.EnvelopedDataStream(is); 445 446 AlgorithmParameterSpec params = null; 447 // get the recipient infos 448 iaik.pkcs.pkcs7.RecipientInfo[] recipients = enveloped_data.getRecipientInfos(); 449 450 System.out.println("\nThis message can be decrypted by the owners of the following certificates:"); 451 452 for (int i=0; i<recipients.length; i++) { 453 System.out.println("Recipient "+(i+1)+":"); 454 System.out.println(recipients[i].getIssuerAndSerialNumber()); 455 } 456 // decrypt symmetric content encryption key, e.g.: 457 SecretKey secretKey = recipients[recipientInfoIndex].decryptKey(user1_pk); 458 459 //get the ECI from the enveloped data: 460 iaik.pkcs.pkcs7.EncryptedContentInfoStream eci = (iaik.pkcs.pkcs7.EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo(); 461 //get the content encryption algorithm: 462 AlgorithmID contentEA = eci.getContentEncryptionAlgorithm(); 463 System.out.println("Content Encryption Algorithm: " + contentEA); 464 if (contentEA.equals(AlgorithmID.rc2_CBC)) { 465 // get the parameters as SEQUENCE 466 SEQUENCE seq = (SEQUENCE)contentEA.getParameter(); 467 // the iv is the second component 468 OCTET_STRING oct = (OCTET_STRING)seq.getComponentAt(1); 469 // create an IvParameterSpec: 470 //params = new IvParameterSpec((byte[])oct.getValue()); 471 int rc2ParameterVersion = ((BigInteger)seq.getComponentAt(0).getValue()).intValue(); 472 int effective_key_bits = 32; 473 switch (rc2ParameterVersion) { 474 case 160: 475 effective_key_bits = 40; 476 break; 477 case 120: 478 effective_key_bits = 64; 479 break; 480 case 58: 481 effective_key_bits = 128; 482 break; 483 default: 484 throw new Exception("Invalid rc2ParameterVersion " + rc2ParameterVersion + "!"); 485 486 } 487 params = new RC2ParameterSpec(effective_key_bits,(byte[])seq.getComponentAt(1).getValue()); 488 489 } 490 else if (contentEA.equals(AlgorithmID.rc5_CBC)) { 491 OCTET_STRING oct = (OCTET_STRING)contentEA.getParameter(); 492 // create an IvParameterSpec: 493 params = new IvParameterSpec((byte[])oct.getValue()); 494 } else if (contentEA.equals(AlgorithmID.arcfour)) { 495 params = null; 496 } else if (contentEA.equals(AlgorithmID.cast5_CBC)) { 497 // get the parameters 498 ASN1Object asn1Params = contentEA.getParameter(); 499 if (asn1Params.isA(ASN.SEQUENCE)) { 500 // the iv is the first component 501 params = new IvParameterSpec((byte[])asn1Params.getComponentAt(0).getValue()); 502 } else { 503 // to be compatible with (invalid) CAST AlgorithmIDs only using the IV as parameters 504 params = new IvParameterSpec((byte[])asn1Params.getValue()); 505 } 506 } else { 507 throw new Exception("Algorithm " + contentEA + " not supportted for this test!"); 508 } 509 510 511 //now setup the cipher with previously decrypted recipient key amd params 512 eci.setupCipher(secretKey, params); 513 //get and read the data thereby actually performing the decryption 514 InputStream data_is = eci.getInputStream(); 515 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 516 Util.copyStream(data_is, baos, null); 517 byte[] decrypted = baos.toByteArray(); 518 return decrypted; 519 520 } 521 522 523 524 /** 525 * Starts the test. 526 */ 527 public void start() { 528 // the test message 529 String m = "This is the test message."; 530 System.out.println("Test message: \""+m+"\""); 531 System.out.println(); 532 byte[] message = m.getBytes(); 533 534 try { 535 byte[] data; 536 byte[] received_message = null; 537 538 539 // the stream implementation 540 // 541 // test CMS EnvelopedDataStream 542 // 543 544 // ARCFOUR 545 System.out.println("\nEnvelopedDataStream demo for algorithm ARCFOUR [create]:\n"); 546 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.arcfour.clone(), 128); 547 // transmit data 548 System.out.println("\nEnvelopedDataStream demo [parse]:\n"); 549 // user1 means index 0 (hardcoded for this demo) 550 received_message = getEnvelopedDataStream(data, user1_pk, 0); 551 System.out.print("\nDecrypted content: "); 552 System.out.println(new String(received_message)); 553 554 // RC2 555 System.out.println("\nEnvelopedDataStream demo for algorithm RC2 [create]:\n"); 556 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 128); 557 // transmit data 558 System.out.println("\nEnvelopedDataStream demo [parse]:\n"); 559 // user1 means index 0 (hardcoded for this demo) 560 received_message = getEnvelopedDataStream(data, user1_pk, 0); 561 System.out.print("\nDecrypted content: "); 562 System.out.println(new String(received_message)); 563 564 // CAST5_CBC 565 System.out.println("\nEnvelopedDataStream demo for algorithm CAST5_CBC [create]:\n"); 566 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.cast5_CBC.clone(), 128); 567 // transmit data 568 System.out.println("\nEnvelopedDataStream demo [parse]:\n"); 569 // user1 means index 0 (hardcoded for this demo) 570 received_message = getEnvelopedDataStream(data, user1_pk, 0); 571 System.out.print("\nDecrypted content: "); 572 System.out.println(new String(received_message)); 573 574 // CMS <---> PKCS#7 575 576 System.out.println("Test compatibility to PKCS#7...."); 577 578 // ARCFOUR 579 System.out.println("\nCMS EnvelopedDataStream demo for algorithm ARCFOUR [create]:\n"); 580 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.arcfour.clone(), 128); 581 // transmit data 582 System.out.println("\nPKCS#7 EnvelopedDataStream demo [parse]:\n"); 583 // user1 means index 0 (hardcoded for this demo) 584 received_message = getPKCS7EnvelopedDataStream(data, user1_pk, 0); 585 System.out.print("\nDecrypted content: "); 586 System.out.println(new String(received_message)); 587 588 System.out.println("\nPKCS#7 EnvelopedDataStream demo for algorithm ARCFOUR [create]:\n"); 589 data = createPKCS7EnvelopedDataStream(message, (AlgorithmID)AlgorithmID.arcfour.clone(), 128); 590 // transmit data 591 System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n"); 592 // user1 means index 0 (hardcoded for this demo) 593 received_message = getEnvelopedDataStream(data, user1_pk, 0); 594 System.out.print("\nDecrypted content: "); 595 System.out.println(new String(received_message)); 596 597 598 // RC2 599 System.out.println("\nCMS EnvelopedDataStream demo for algorithm RC2 [create]:\n"); 600 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 128); 601 // transmit data 602 System.out.println("\nPKCS#7 EnvelopedDataStream demo [parse]:\n"); 603 // user1 means index 0 (hardcoded for this demo) 604 received_message = getPKCS7EnvelopedDataStream(data, user1_pk, 0); 605 System.out.print("\nDecrypted content: "); 606 System.out.println(new String(received_message)); 607 608 System.out.println("\nPKCS#7 EnvelopedDataStream demo for algorithm RC2 [create]:\n"); 609 data = createPKCS7EnvelopedDataStream(message, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 128); 610 // transmit data 611 System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n"); 612 // user1 means index 0 (hardcoded for this demo) 613 received_message = getEnvelopedDataStream(data, user1_pk, 0); 614 System.out.print("\nDecrypted content: "); 615 System.out.println(new String(received_message)); 616 617 // CAST5_CBC 618 System.out.println("\nCMS EnvelopedDataStream demo for algorithm CAST5_CBC [create]:\n"); 619 data = createEnvelopedDataStream(message, (AlgorithmID)AlgorithmID.cast5_CBC.clone(), 128); 620 // transmit data 621 System.out.println("\nPKCS#7 EnvelopedDataStream demo [parse]:\n"); 622 // user1 means index 0 (hardcoded for this demo) 623 received_message = getPKCS7EnvelopedDataStream(data, user1_pk, 0); 624 System.out.print("\nDecrypted content: "); 625 System.out.println(new String(received_message)); 626 627 System.out.println("\nPKCS#7 EnvelopedDataStream demo for algorithm CAST5_CBC [create]:\n"); 628 data = createPKCS7EnvelopedDataStream(message, (AlgorithmID)AlgorithmID.cast5_CBC.clone(), 128); 629 // transmit data 630 System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n"); 631 // user1 means index 0 (hardcoded for this demo) 632 received_message = getEnvelopedDataStream(data, user1_pk, 0); 633 System.out.print("\nDecrypted content: "); 634 System.out.println(new String(received_message)); 635 636 } catch (Exception ex) { 637 ex.printStackTrace(); 638 throw new RuntimeException(ex.toString()); 639 } 640 } 641 642 /** 643 * The main method. 644 * 645 * @throws IOException 646 * if an I/O error occurs when reading required keys 647 * and certificates from files 648 */ 649 public static void main(String argv[]) throws Exception { 650 651 DemoUtil.initDemos(); 652 653 (new PKCS7CMSEncryptedContentInfoDemo()).start(); 654 System.out.println("\nReady!"); 655 DemoUtil.waitKey(); 656 } 657}