iaik.cms
Class EncryptedData

java.lang.Object
  extended by iaik.cms.EncryptedDataStream
      extended by iaik.cms.EncryptedData
All Implemented Interfaces:
Content, ContentStream, EOFListener, java.util.EventListener

public class EncryptedData
extends EncryptedDataStream
implements Content

This class represents the non-stream implemention of the CMS EncryptedData type.

Each CMS content type is associated with a specific object identifier, derived from:

 pkcs-7 OBJECT IDENTIFIER ::=
   { iso(1) member-body(2) US(840) rsadsi(113549)
       pkcs(1) 7 }
 

The object identifier for the EncryptedData content type is defined as:

encryptedData OBJECT IDENTIFIER ::= { pkcs-7 6 }

which corresponds to the OID string "1.2.840.113549.1.7.6".

The Cryptographic Message Syntax (CMS) ( RFC 5652) specifies the EncryptedData content type for providing a syntax for building encrypted contents. The encrypted-data content type consists of encrypted content of any type:

 EncryptedData ::= SEQUENCE {
    version CMSVersion,
    encryptedContentInfo EncryptedContentInfo 
    unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
 

The encryptedContentInfo field specifies the type of the content being encrypted, the content-encryption algorithm used for encrypting the content, and the result of the content encryption. If the encrypted content value is not present in the encryptedContent field, it has to be supplied by other means:

 EncryptedContentInfo ::= SEQUENCE {
   contentType                 ContentType,
   contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
   encryptedContent            [0] IMPLICIT EncryptedContent OPTIONAL }
 
EncryptedContent ::= OCTET STRING

The key that is used for encrypting the content is not included in the EncryptedData structure, it is assumed to be managed by other means.

If unprotected attributes are present, the version number is 2; otherwise 0:

 UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
 


When creating a new EncryptedData instance the encrypted content has to be supplied as EncryptedContentInfo object.

Example:

 //create a EncryptedContentInfo for the data to be encrypted, supplied as byte array:
 byte[] data = ...;
 EncryptedContentInfo eci = new EncryptedContentInfo(ObjectID.cms_data, data);
 //generate secret key and use it for encrypting the content :
 SecretKey key = eci.setupCipher((AlgorithmID)AlgorithmID.des_EDE3_CBC.clone());
 //create an EncryptedData for the EncryptedContentInfo:
 EncryptedData encrypted_data = new EncryptedData(eci);
 //Prepare the EncryptedData for transmission by transforming it into an ASN1Object or
 //immediately performing the DER encoding:
 ASN1Object = encrypted_data.toASN1Object();
 //respectively byte[] encoding = encrypted_data.getEncoded();
 
For initiating a constructed encoding of the inherent encrypted content, use the corresponding writeTo method of the parent EncryptedDataStream class, or set a positive blocksize value for the inherent EncryptedContentInfo by means of the setBlockSize method of the EncryptedContentInfo class. If a positive blocksize is specified, the encrypted content of the inherent EncryptedContentInfo will be encoded as indefinite primitive octet string instead of using the default primitive definite encoding scheme:
 0x24 0x80
           0x04 <blocksize> <first encrypted content block>
           0x04 <blocksize> <second encrypted content block>
           0x04 <blocksize> <third encrypted content block>
                ...
 0x00 0x00
 
instead of:
 0x04 <length> <encrypted content>
 

Decrypting goes the reverse way: From the DER encoded encryptedData a new EncryptedData is created and parsed for the inherent EncryptedContentInfo. From the EncryptedContentInfo the encrypted content is obtained and decrypted using the same secret key:

 //create an EncryptedData from its DER encoding:
 ByteArrayInputStream bais = new ByteArrayInputStream(encoding);
 EncryptedData encryptedData = new EncryptedDataStream(bais);
 EncryptedContentInfo eci =  (EncryptedContentInfo)encryptedData.getEncryptedContentInfo();
 //decrypt the encrypted content using the right secret key:
 eci.setupCipher(key);
 //get the recovered data:
 byte[] data = eci.getContent();
 


This class additonally supports specific constructors and methods allowing to easily use the EncryptedData content type for password based encrypting data -- the intended usage of CMS EncryptedData. Please remark that the follwoing proceeding only may be used when doing a password based encryption. In all other situations you have to follow the way described above. However, you also may create your own EncryptedContentInfo even when doing a PBE encryption.

If you want to use PBE encryption but not creating an EncryptedContentInfo by yourself you first have to supply the data to be read from an byte array, subsequently setup the cipher for PBE-encryption and finally call a toASN1Object, getEncoded or writeTo method for preparing the EncryptedData object for transmission by transforming it into an ASN1Object or immediately encoding it, e.g.:

  1. Use the EncryptedData(byte[] data) constructor for creating a new EncryptedData object and supplying the data to be encrypted from a byte array:
         //the data to be encrypted supplied from a byte array:
         byte[] data = ...;
         EncryptedData encrypted_data = new EncryptedData(data);
         
  2. Setup the cipher for encryption by calling method setupCipher(AlgorithmID contentEA, char[] password) thereby specifying the PBE-algorithm to be used and the password, e.g.:
         AlgorithmID pbeAlgorithm = (AlgorithmID)AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.clone();
         char[] password = ...;
         encrypted_data.setupCipher(pbeAlgorithm, password);
         
  3. Prepare the EncryptedData object for transmission by transforming it into an ASN1Object or immediately DER encoding it. The former is done by calling the toASN1Object method, the latter by using the getEncoded method:
         ASN1Object obj = encrypted_data.toASN1Object();
         
    respectively
         byte[] encoding = encrypted_data.getEncoded();
         
    You alternatively may use a proper writeTo method of the parent EncryptedDataStream class for immediately encoding this EncryptedData object to an output stream. When a positve block size is specified for encoding the EncryptedData to a stream, the encrypted content is BER encoded as indefinite constructed octet string being composed of a series of definite primitive encoded octet strings of blockSize length:
         0x24 0x80
                   0x04 <blocksize> <first encrypted content block>
                   0x04 <blocksize> <second encrypted content block>
                   0x04 <blocksize> <third encrypted content block>
                       ...
         0x00 0x00
         
    instead of:
         0x04 <length> <encrypted content>
         
For parsing the EncryptedData object and recovering the original content, first use the EncryptedData(ASN1Object obj) or EncryptedData(InputStream is) constructor to parse the internal structure. Before reading the recovered content by means of the getContent method, the cipher has to be initialized for decryption with the password by calling the setupCipher(char[] password) method:
  1. Create an EncryptedData structure from the supplied encoding, decode and parse the internal structure:
          ByteArrayInputStream bais = new ByteArrayInputStream(encoding);
         EncryptedData encryptedData = new EncryptedDataStream(bais);
         
  2. Get information about the inherent EncryptedContentInfo:
         EncryptedContentInfoStream eci = (EncryptedContentInfo)encrypted_data.getEncryptedContentInfo();
         System.out.println("Content type: "+eci.getContentType().getName());
         System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
         
  3. Specify the passord for initializing the cipher for encrypted-content decryption:
         char[] password = ...;
         encrypted_data.setupCipher(password);
         
    Unlike the stream supporting EncryptedDataStream class where the setupCipher method only initializes the cipher for decryption, whole the encrypted-content decryption already is performed inside the setupCipher method of this class.

  4. Get the recovered content:
         byte[] content = encrypted_data.getContent();
         

See Also:
EncryptedContentInfo

Field Summary
 
Fields inherited from class iaik.cms.EncryptedDataStream
blockSize_, encryptedContentInfo_, securityProvider_, unprotectedAttrs_, version_
 
Constructor Summary
protected EncryptedData()
          Default constructor for dynamic object creation in ContentInfo.
  EncryptedData(ASN1Object obj)
          Creates an EncryptedData object from the given ASN1 object.
  EncryptedData(byte[] data)
          Creates a new CMS EncryptedData object where the content to be encrypted is read from the supplied byte array.
  EncryptedData(EncryptedContentInfo encryptedContentInfo)
          Creates a CMS EncryptedData from an EncryptedContentInfo.
  EncryptedData(java.io.InputStream is)
          Creates a new EncryptedData from a DER encoded EncryptedData which is read from the given InputStream.
  EncryptedData(ObjectID contentType, byte[] data)
          Creates a new CMS EncryptedData object where the content to be encrypted is read from the supplied byte array.
 
Method Summary
 void decode(ASN1Object obj)
          Decodes the given EncryptedData ASN1 object.
 void decode(java.io.InputStream is)
          Reads and decodes an encoded EncryptedData from the given input stream.
 byte[] getContent()
          Returns the content as byte array.
 byte[] getEncoded()
          Returns the DER encoding of this EncryptedData in a byte array.
 void setInputStream(java.io.InputStream is)
          Throws a RuntimeException since not supported.
protected  ASN1Object toASN1Object(int blockSize)
          Returns this EncryptedData as ASN1Object where a constructed OCTET STRING is used for encoding the encrypted content.
 
Methods inherited from class iaik.cms.EncryptedDataStream
getBlockSize, getContentType, getEncryptedContentInfo, getInputStream, getSecurityProvider, getUnprotectedAttribute, getUnprotectedAttributes, getVersion, notifyEOF, setBlockSize, setSecurityProvider, setUnprotectedAttributes, setupCipher, setupCipher, setupCipher, setupCipher, setupCipher, toASN1Object, toString, toString, writeTo, writeTo
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface iaik.cms.ContentStream
getBlockSize, getContentType, setBlockSize, toASN1Object, toString
 

Constructor Detail

EncryptedData

protected EncryptedData()
Default constructor for dynamic object creation in ContentInfo. The block size is set to -1 to enforce definite primitive encoding.


EncryptedData

public EncryptedData(EncryptedContentInfo encryptedContentInfo)
Creates a CMS EncryptedData from an EncryptedContentInfo.

Parameters:
encryptedContentInfo - the already created encrypted content info

EncryptedData

public EncryptedData(byte[] data)
Creates a new CMS EncryptedData object where the content to be encrypted is read from the supplied byte array.
The content type is set to CMS Data.

This constructor only shall be used when intending to PBE encrypt the data by subsequently calling method setupCipher thereby supplying PBE-algorithm and password to be used.
This constructor shall not be used in situations where the desired content encryption algorithm is not a PBE algorithm. In such cases the EncryptedData(EncryptedContentInfo) constructor shall be used to be supplied with a precomputed EncryptedContentInfo. Consult the EncryptedContentInfo class documentation for more information about EncryptedContentInfo handling.

Parameters:
data - the byte array containing the data to encrypt

EncryptedData

public EncryptedData(ObjectID contentType,
                     byte[] data)
Creates a new CMS EncryptedData object where the content to be encrypted is read from the supplied byte array.
The content type is set to CMS Data.

This constructor only shall be used when intending to PBE encrypt the data by subsequently calling method setupCipher thereby supplying PBE-algorithm and password to be used.
This constructor shall not be used in situations where the desired content encryption algorithm is not a PBE algorithm. In such cases the EncryptedData(EncryptedContentInfo) constructor shall be used to be supplied with a precomputed EncryptedContentInfo. Consult the EncryptedContentInfo class documentation for more information about EncryptedContentInfo handling.

Parameters:
data - the byte array containing the data to encrypt

EncryptedData

public EncryptedData(ASN1Object obj)
              throws CMSParsingException
Creates an EncryptedData object from the given ASN1 object. The ASN.1 EncryptedData may (or may not) be wrapped into a ContentInfo.

The ASN1Object supplied to this constructor represents an already exisiting EncryptedData object that may have been created by calling toASN1Object.

Parameters:
obj - the ASN1Object representing an already exisiting EncryptedData object.
Throws:
CMSParsingException - if an error occurs when parsing the given ASN1Object

EncryptedData

public EncryptedData(java.io.InputStream is)
              throws java.io.IOException,
                     CMSParsingException
Creates a new EncryptedData from a DER encoded EncryptedData which is read from the given InputStream. The encoded EncryptedData may (or may not) be wrapped into a ContentInfo.

Parameters:
is - the InputStream holding a DER encoded EncryptedData object
Throws:
java.io.IOException - if an I/O error occurs during reading from the InputStream
CMSParsingException - if an error occurs while parsing the object
Method Detail

decode

public void decode(ASN1Object obj)
            throws CMSParsingException
Decodes the given EncryptedData ASN1 object. The ASN.1 EncryptedData may (or may not) be wrapped into a ContentInfo.

Specified by:
decode in interface Content
Parameters:
obj - the ASN1Object representing an already exisiting EncryptedData object
Throws:
CMSParsingException - if an error occurs when parsing the given ASN1Object

decode

public void decode(java.io.InputStream is)
            throws java.io.IOException,
                   CMSParsingException
Reads and decodes an encoded EncryptedData from the given input stream. The encoded EncryptedData may (or may not) be wrapped into a ContentInfo.

Specified by:
decode in interface ContentStream
Overrides:
decode in class EncryptedDataStream
Parameters:
is - the InputStream holding a DER encoded EncryptedData object
Throws:
java.io.IOException - if an I/O error occurs during reading from the InputStream
CMSParsingException - if an error occurs while parsing the object

getContent

public byte[] getContent()
Returns the content as byte array.

The returned content depends on whether creating a new EncryptedData or parsing an existing one:

Returns:
a byte array holding the content

setInputStream

public void setInputStream(java.io.InputStream is)
Throws a RuntimeException since not supported. This method only overrides the same named method of parent class EncryptedDataStream but throws a RuntimeException since this method is not supported by this class. The to-be-encrypted content has to be supplied when creating an EncryptedData object.

Overrides:
setInputStream in class EncryptedDataStream
Parameters:
is - ignored
Throws:
RuntimeRuntimeException - since method is not supported

toASN1Object

protected ASN1Object toASN1Object(int blockSize)
                           throws CMSException
Returns this EncryptedData as ASN1Object where a constructed OCTET STRING is used for encoding the encrypted content.

Overrides:
toASN1Object in class EncryptedDataStream
Parameters:
blockSize - the block size defining the encoding scheme - and specifying the length of each primitive encoded octet string component, if positive
Returns:
this EncryptedData as ASN1Object
Throws:
CMSException - if the ASN1Object could not be created

getEncoded

public byte[] getEncoded()
                  throws CMSException
Returns the DER encoding of this EncryptedData in a byte array.

If the blockSize value of the inherent EncryptedContentInfo structure has been set to a positive value, the encrypted content is encoded as indefinite constructed octet string being composed of a certain number of definite primitive encoded octet strings of blockSize length. If no - or a not-positive - blockSize value has been specified whole the encrypted content will be encoded as definite primitive octet string.

Returns:
a byte array holding the DER encoding of this EncryptedData
Throws:
CMSException - if an error occurs during the encoding procedure

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

IAIK-CMS 5.1, (c) 2002 IAIK, (c) 2003 - 2010 SIC