iaik.cms
Class EncryptedDataOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by iaik.cms.EncryptedDataOutputStream
All Implemented Interfaces:
java.io.Closeable, java.io.Flushable

public class EncryptedDataOutputStream
extends java.io.OutputStream

This is an OutputStream implementation of the CMS (RFC 5652) EncryptedData structure.

This stream version will encode the encrypted content as a constructed OCTET STRING. Each write operation to this stream will result in an OCTET STRING block within this constructed OCTET STRING provided that the input data is at least as large as the block size of the employed (block) cipher. Calling close() will finish the encryption, i.e. it will do the padding and finish writing the resulting EncryptedData structure. Consequently, if a block cipher is used, the size of a block in the OCTET STRING will be a multiple of the block size of the cipher (e.g. 16 Byte for AES).

The inherent cipher must be setup for encryption before the application starts writing data to this stream. A typical use case may be to write data password based encrypted to some (file) output stream, e.g.:

  // the password to be used
  char[] password = ...;
  // the input stream from which to read the data to be encrypted
  InputStream dataInputStream = ...
  // the output stream to which to write the EncryptedData
  OutputStream resultStream = ...
  
  // create encrypted data stream 
  EncryptedDataOutputStream encryptingStream = 
    new EncryptedDataOutputStream(resultStream);
  // setup cipher for encryption (in this sample we use PbeWithSHAAnd3-KeyTripleDES-CBC
  // as content encryption algorithm)
  AlgorithmID contentEncAlg = (AlgorithmID)AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.clone();
  encryptingStream.setupCipher(contentEncAlg, password);
  
  // write in the data to be encrypted
  byte[] buffer = new byte[2048];
  int bytesRead;
  while ((bytesRead = dataInputStream.read(buffer)) != -1) {
    encryptingStream.write(buffer, 0, bytesRead);
  }
  // closing the stream finishes encryption and closes the underlying stream
  encryptingStream.close();
 
If you want to encapsulate the EncryptedData into a ContentInfo you first must wrap a ContentInfoOutputStream around the final output stream (the ContentInfoStream has to write its headers to the stream at first, thus it must be created at the "lowest" level):
  ContentInfoOutputStream contentInfoStream = 
    new ContentInfoOutputStream(ObjectID.cms_encryptedData, resultStream);
  // now create EncryptedDataOutputStream for the ContentInfoStream:
  EncryptedDataOutputStream encryptingStream = 
    new EncryptedDataOutputStream(contentInfoStream);  
    
  // the further proceeding is same as above 
  AlgorithmID contentEncAlg = (AlgorithmID)AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.clone();
  encryptingStream.setupCipher(contentEncAlg, password);
  
  // write in the data to be encrypted
  byte[] buffer = new byte[2048];
  int bytesRead;
  while ((bytesRead = dataInputStream.read(buffer)) != -1) {
    encryptingStream.write(buffer, 0, bytesRead);
  }
  // closing the stream finishes encryption and closes the underlying stream
  encryptingStream.close();
 
If you do not want to use pbe encryption, you explicitly can specify the symmetric content encryption key when setting up the cipher for encryption, e.g.:
 KeyGenerator keyGen = KeyGenerator.getInstance("AES", "IAIK");
 SecretKey key = keyGen.generateKey();
 ...
 AlgorithmID contentEncAlg = (AlgorithmID)AlgorithmID.aes128_CBC.clone();
 encryptingStream.setupCipher(contentEncAlg, key, null);
 ...
 
Use class EncryptedDataStream to read in and parse the EncryptedData and decrypt the encrypted content.

See Also:
EncryptedDataStream

Constructor Summary
EncryptedDataOutputStream(ObjectID contentType, java.io.OutputStream out)
          Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g.
EncryptedDataOutputStream(ObjectID contentType, java.io.OutputStream out, SecurityProvider securityProvider)
          Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g.
EncryptedDataOutputStream(java.io.OutputStream out)
          Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g.
 
Method Summary
 void close()
          Finishes encryption/encoding and writes any unprotected attributes (if set) to the underlying stream.
 void flush()
          Flushes any internal data and calls flush of the underlying stream.
 SecurityProvider getSecurityProvider()
          Gets the SecurityProvider installed for this EncryptedDataOutputStream.
 int getVersion()
          Returns the syntax version number.
 boolean isPassThroughClose()
          Checks whether a call to close() will call close of the underlying output stream
 void setPassThroughClose(boolean passThroughClose)
          Setting this to true will cause close() to call close of the underlying output stream.
 void setSecurityProvider(SecurityProvider securityProvider)
          Sets the SecurityProvider for this EncryptedDataOutputStream.
 void setUnprotectedAttributes(Attribute[] attributes)
          Sets a set of (unprotected) attributes.
 void setupCipher(AlgorithmID contentEA, char[] password)
          Setups the cipher for PBE-encrypting the content.
 void setupCipher(AlgorithmID contentEA, char[] password, int iterationCount)
          Setups the cipher for PBE-encrypting the content.
 void setupCipher(AlgorithmID contentEA, java.security.Key key, java.security.spec.AlgorithmParameterSpec paramSpec)
          Setups the cipher for encrypting the content with the given secret key.
 java.lang.String toString()
          Returns a string giving some information about this EncryptedDataOutputStream object.
 java.lang.String toString(boolean detailed)
          Returns a string giving some - if requested - detailed information about this EncryptedData object.
 void write(byte[] b)
          Encrypts, encodes and writes the given data to the output stream.
 void write(byte[] b, int off, int len)
          Encrypts, encodes and writes the given data to the output stream.
 void write(int b)
          Encrypts, encodes and writes the given data byte to the output stream.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

EncryptedDataOutputStream

public EncryptedDataOutputStream(java.io.OutputStream out)
Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g. write(byte[])).
The content type is set to CMS Data.

Parameters:
out - the OutputStream receiving the encrypted data

EncryptedDataOutputStream

public EncryptedDataOutputStream(ObjectID contentType,
                                 java.io.OutputStream out)
Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g. write(byte[])).

Parameters:
contentType - the content type of the content to be encrypted
out - the OutputStream receiving the encrypted data

EncryptedDataOutputStream

public EncryptedDataOutputStream(ObjectID contentType,
                                 java.io.OutputStream out,
                                 SecurityProvider securityProvider)
Creates a new EncryptedDataOutputStream object where the content to be encrypted is later written to the given output stream (e.g. write(byte[])).

Parameters:
contentType - the content type of the content to be encrypted
out - the OutputStream receiving the encrypted data
securityProvider - the SecurityProvider to be used
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm
Method Detail

setupCipher

public void setupCipher(AlgorithmID contentEA,
                        char[] password)
                 throws java.security.NoSuchAlgorithmException,
                        java.security.InvalidKeyException
Setups the cipher for PBE-encrypting the content.
This method may be used to setup the cipher for PBE-encrypting the content. The content encryption actually is performed during the encoding when calling write(byte[]), write(int) or write(byte[], int, int). Thus it is important to setup the cipher before writing to the stream!
When using this method the iteration count used to derive the secret content encryption key from the password is set to 10000. If you want to use a different iteration count value, use method setupCipher(AlgorithmID, char[], int).

Parameters:
contentEA - the PBE-algorithm to be used
password - the password
Throws:
java.security.NoSuchAlgorithmException - if the algorithm is not supported
java.security.InvalidKeyException - if the key cannot be derived from the password

setupCipher

public void setupCipher(AlgorithmID contentEA,
                        char[] password,
                        int iterationCount)
                 throws java.security.NoSuchAlgorithmException,
                        java.security.InvalidKeyException
Setups the cipher for PBE-encrypting the content.
This method may be used to setup the cipher for PBE-encrypting the content. The content encryption actually is performed during the encoding when calling write(byte[]), write(int) or write(byte[], int, int). Thus it is important to setup the cipher before writing to the stream!

This method has an additional parameter: iterationCount. When deriving the symmetric key and the IV a hash is calculated iterationCount times on the password and on the salt for increasing the cost for breaking the cipher using brute force methods. The default iteration count value is 10000.

Parameters:
contentEA - the PBE-algorithm to be used
password - the password
iterationCount - the iteration count for key derivation
Throws:
java.security.NoSuchAlgorithmException - if the algorithm is not supported
java.security.InvalidKeyException - if the key cannot be derived from the password

setupCipher

public void setupCipher(AlgorithmID contentEA,
                        java.security.Key key,
                        java.security.spec.AlgorithmParameterSpec paramSpec)
                 throws java.security.NoSuchAlgorithmException,
                        java.security.InvalidKeyException
Setups the cipher for encrypting the content with the given secret key.
The content encryption actually is performed during the encoding when calling write(byte[]), write(int) or write(byte[], int, int). Thus it is important to setup the cipher before writing to the stream!

Parameters:
contentEA - the content encryption algorithm to be used
key - the content encryption key to be used
paramSpec - any required parameters (maybe null if no parameters are required or you want to let the cipher create the paramters (e.g. iv))
Throws:
java.security.NoSuchAlgorithmException - if the algorithm is not supported
java.security.InvalidKeyException - if the key cannot be used

write

public void write(byte[] b,
                  int off,
                  int len)
           throws java.io.IOException
Encrypts, encodes and writes the given data to the output stream.

Overrides:
write in class java.io.OutputStream
Parameters:
b - The data to be encrypted
off - The start offset in b.
len - The number of bytes to write.
Throws:
java.io.IOException - If an I/O error occurs.

write

public void write(byte[] b)
           throws java.io.IOException
Encrypts, encodes and writes the given data to the output stream.

Overrides:
write in class java.io.OutputStream
Parameters:
b - The data to be encrypted.
Throws:
java.io.IOException - If an I/O error occurs.

write

public void write(int b)
           throws java.io.IOException
Encrypts, encodes and writes the given data byte to the output stream.

Specified by:
write in class java.io.OutputStream
Parameters:
b - The data byte to be encrypted.
Throws:
java.io.IOException - If an I/O error occurs.

flush

public void flush()
           throws java.io.IOException
Flushes any internal data and calls flush of the underlying stream.

Specified by:
flush in interface java.io.Flushable
Overrides:
flush in class java.io.OutputStream
Throws:
java.io.IOException - If flushing the stream fails.

close

public void close()
           throws java.io.IOException
Finishes encryption/encoding and writes any unprotected attributes (if set) to the underlying stream.

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.OutputStream
Throws:
java.io.IOException

isPassThroughClose

public boolean isPassThroughClose()
Checks whether a call to close() will call close of the underlying output stream

Returns:
true if a call to close() will call close of the underlying output stream; false if a call to close() will not close the underlying stream.

setPassThroughClose

public void setPassThroughClose(boolean passThroughClose)
Setting this to true will cause close() to call close of the underlying output stream. If false, a call to close() will not close the underlying stream.

Parameters:
passThroughClose - true to pass through close() calls. false to not pass them through.

setSecurityProvider

public void setSecurityProvider(SecurityProvider securityProvider)
Sets the SecurityProvider for this EncryptedDataOutputStream.

This method allows to explicitly set a SecurityProvider for this EncryptedDataOutputStream. If no explicit SecurityProvider is set, the default system wide installed SecurityProvider will be used for the required cryptographic operations.

This class uses the following method(s) of the SecurityProvider, which may be overriden by an application, if required:

An application may supply the SecurityProvider immediately when creating an EncryptedDataOutputStream object.

Parameters:
securityProvider - the SecurityProvider to be set

getSecurityProvider

public SecurityProvider getSecurityProvider()
Gets the SecurityProvider installed for this EncryptedDataOutputStream.

This class uses the following method(s) of the SecurityProvider, which may be overriden by an application, if required:

If no explicit SecurityProvider has been set for this object, the default system wide installed SecurityProvider will be used for the required cryptographic operations. However, this method will return null if it does not have its own SecurityProvider.

Returns:
the SecurityProvider explicitly installed for this object, or null if this object does not have its own SecurityProvider

setUnprotectedAttributes

public void setUnprotectedAttributes(Attribute[] attributes)
Sets a set of (unprotected) attributes.

Parameters:
attributes - the unprotected attributes to be set

getVersion

public int getVersion()
Returns the syntax version number.

Returns:
the syntax version number

toString

public java.lang.String toString()
Returns a string giving some information about this EncryptedDataOutputStream object.

Overrides:
toString in class java.lang.Object
Returns:
the string representation

toString

public java.lang.String toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this EncryptedData object.

Parameters:
detailed - - whether or not to give detailed information
Returns:
the string representation

This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

IAIK-CMS 6.0, (c) 2002 IAIK, (c) 2003, 2023 SIC