iaik.pkcs.pkcs7
Class EncryptedData

java.lang.Object
  |
  +--iaik.pkcs.pkcs7.EncryptedDataStream
        |
        +--iaik.pkcs.pkcs7.EncryptedData
All Implemented Interfaces:
Content, ContentStream

public class EncryptedData
extends EncryptedDataStream
implements Content

This class represents the non-stream implemention of the PKCS#7 EncryptedData type.

Each PKCS#7 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.1.113549.1.7.6".

The PKCS#7 Cryptographic Message Standard 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 (Version 1.5):

 EncryptedData ::= SEQUENCE {
    version Version,
    encryptedContentInfo EncryptedContentInfo }
 

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.


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.pkcs7_data, data);
 //generate secret key and use it for encrypting the content :
 SecretKey key = eci.setupCipher(AlgorithmID.des_EDE3_CBC);
 //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>
 
The indefinte constrcuted encoding scheme may be preferable when intending to be compatible to the encoding practice of some particular application (for instance some versions of Netscape Navigator).

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:

 //if the EncryptedData is given as DER encoding, first decode it to an ASN1Object:
 ASN1Object obj = DerCoder.decode(encoding);
 EncryptedData encryptedData = new EncryptedDataStream(obj);
 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 PKCS#7 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.pbeWithSHAAnd3_KeyTripleDES_CBC;
         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>
         
    The indefinte constrcuted encoding scheme also may be preferable when intending to be compatible to the encoding practice of some particular application (for instance some versions of Netscape Navigator).
For parsing the EncryptedData object and recovering the original content, first use the EncryptedData(ASN1Object obj) constructor to parse the internal structure. Before reading the recovered content by means of the getInputStream method, the cipher has to be initialized for decryption with the password by calling the setupCipher(char[] password) method:
  1. Create an EncryptedDataStream structure from the supplied encoding, decode and parse the internal structure:
         EncryptedDataStream encrypted_data = new EncryptedDataStream(encoded_stream);
         
  2. Get information about the inherent EncryptedContentInfo:
         EncryptedContentInfoStream eci = (EncryptedContentInfoStream)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();
         

Version:
File Revision 34
See Also:
EncryptedContentInfo

Fields inherited from class iaik.pkcs.pkcs7.EncryptedDataStream
block_size, 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 PKCS#7 EncryptedData object where the content to be encrypted is read from the supplied byte array.
  EncryptedData(EncryptedContentInfo encryptedContentInfo)
          Creates a PKCS#7 EncryptedData from an EncryptedContentInfo.
  EncryptedData(InputStream is)
          Creates a new EncryptedData where the DER encoded data is read from the given InputStream.
 
Method Summary
 void decode(ASN1Object obj)
          Decodes the given EncryptedData ASN1 object.
 void decode(InputStream is)
          Reads and decodes the EncryptedData from a DerInputStream.
 byte[] getContent()
          Returns the content as byte array.
 byte[] getEncoded()
          Returns the DER encoding of this EncryptedData in a byte array.
 Object getEncryptedContentInfo()
          Returns the encrypted content info of this EncryptedData object.
 InputStream getInputStream()
          Returns an InputStream for reading the content.
 void setupCipher(AlgorithmID contentEA, char[] password, int iterationCount)
          Setups the cipher for PBE-encrypting the content.
 void setupCipher(char[] password)
          Uses the given password to setup the cipher for decrypting the content.
protected  ASN1Object toASN1Object(int blockSize)
          Returns this PKCS#7 EncryptedData as ASN1Object where a constructed OCTET STRING is used for encoding the encrypted content.
 String toString(boolean detailed)
          Returns a string giving some - if requested - detailed information about this EncryptedData object.
 
Methods inherited from class iaik.pkcs.pkcs7.EncryptedDataStream
getBlockSize, getContentType, getVersion, setBlockSize, setupCipher, toASN1Object, 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.pkcs.pkcs7.ContentStream
getBlockSize, getContentType, setBlockSize, toASN1Object
 

Constructor Detail

EncryptedData

protected EncryptedData()
Default constructor for dynamic object creation in ContentInfo. The block size is set to -1 meaning that the data will be encoded a one simple octet string by deafult.

EncryptedData

public EncryptedData(EncryptedContentInfo encryptedContentInfo)
Creates a PKCS#7 EncryptedData from an EncryptedContentInfo.
Parameters:
encryptedContentInfo - the already created encrypted content info

EncryptedData

public EncryptedData(byte[] data)
Creates a new PKCS#7 EncryptedData object where the content to be encrypted is read from the supplied byte array. The content type is set to PKCS#7 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 PKCSParsingException
Creates an EncryptedData object from the given ASN1 object.

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:
PKCSParsingException - if an error occurs when parsing the given ASN1Object

EncryptedData

public EncryptedData(InputStream is)
              throws IOException,
                     PKCSParsingException
Creates a new EncryptedData where the DER encoded data is read from the given InputStream.
Parameters:
is - the InputStream holding a DER encoded PKCS#7 EncryptedData object
Throws:
IOException - if an I/O error occurs during reading from the InputStream
PKCSParsingException - if an error occurs while parsing the object
Method Detail

decode

public void decode(ASN1Object obj)
            throws PKCSParsingException
Decodes the given EncryptedData ASN1 object.
Specified by:
decode in interface Content
Parameters:
obj - the ASN1Object representing an already exisiting EncryptedData object
Throws:
PKCSParsingException - if an error occurs when parsing the given ASN1Object

decode

public void decode(InputStream is)
            throws IOException,
                   PKCSParsingException
Reads and decodes the EncryptedData from a DerInputStream. If the supplied InputStream actually is not an instance of DerInputStream, internally a DerInputStream is created before parsing the data.
Specified by:
decode in interface ContentStream
Overrides:
decode in class EncryptedDataStream
Parameters:
is - the InputStream holding a DER encoded PKCS#7 EncryptedData object
Throws:
IOException - if an I/O error occurs during reading from the InputStream
PKCSParsingException - if an error occurs while parsing the object

setupCipher

public void setupCipher(AlgorithmID contentEA,
                        char[] password,
                        int iterationCount)
                 throws NoSuchAlgorithmException,
                        InvalidKeyException
Setups the cipher for PBE-encrypting the content. This method only may be used to setup the cipher for PBE-encrypting the content that has been supplied when creating the EncryptedData object by means of the EncryptedData(byte[]) constructor.
In contrast to the same-name method of the parent EncryptedDataStream class, where the cipher only is initialized, in this class this method already performs the content encryption.

The iterationCount parameter has the following meaning: when deriving the symmetric key and the IV a hash is calculated iterationCount times on the password and on the salt thus increasing the cost for breaking the cipher using brute force methods.

Overrides:
setupCipher in class EncryptedDataStream
Parameters:
contentEA - the PBE-algorithm to be used
password - the password
iterationCount - the iteration count for key derivation
Throws:
NoSuchAlgorithmException - if the algorithm is not supported
InvalidKeyException - if the key cannot be derived from the password

setupCipher

public void setupCipher(char[] password)
                 throws NoSuchAlgorithmException,
                        InvalidAlgorithmParameterException,
                        InvalidParameterSpecException,
                        InvalidKeyException
Uses the given password to setup the cipher for decrypting the content.

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.

Attention! This method only can be used when the content has been encrypted using a PBE cipher. Otherwise the setupCipher(Key key, AlgorithmParameterSpec) method of the EncryptedContentInfo class has to be used to setup the cipher for content decryption.

Overrides:
setupCipher in class EncryptedDataStream
Parameters:
password - the password
Throws:
NoSuchAlgorithmException - if the algorithm is not supported
InvalidKeyException - if the key cannot be derived from the password
InvalidAlgorithmParameterException - if the paramters cannot be retrieved from the algorithm ID
InvalidParameterSpecException - if the paramters cannot be set up

getInputStream

public InputStream getInputStream()
Returns an InputStream for reading the content.

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

This method only overrides the corresponding getInputStream method of the parent EncryptedDataStream class for returning the content of this EncryptedData object. There should be no real necessity for using this method since the content bytes immediately can be obtained by the getContent method. However, in contrast to the equivalent getInputStream method of the parent EncryptedDataStream class, this method may be called arbitrarly often; it only returns a ByteArrayInputStream that is initialized with the content bytes.
Overrides:
getInputStream in class EncryptedDataStream
Returns:
an InputStream holding the content

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

toASN1Object

protected ASN1Object toASN1Object(int blockSize)
                           throws PKCSException
Returns this PKCS#7 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 PKCS#7 EncryptedData as ASN1Object
Throws:
PKCSException - if the ASN1Object could not be created

getEncryptedContentInfo

public Object getEncryptedContentInfo()
Returns the encrypted content info of this EncryptedData object. When calling this method for obtaining the inherent EncryptedContentInfo an explicit cast to EncryptedContentInfo has to be made:
 EncryptedContentInfo eci = (EncryptedContentInfo)encrypted_data.getEncryptedContentInfo();
 
Overrides:
getEncryptedContentInfo in class EncryptedDataStream
Returns:
the EncryptedContentInfo

getEncoded

public byte[] getEncoded()
                  throws PKCSException
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:
PKCSException - if an error occurs during the encoding procedure

toString

public String toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this EncryptedData object.
Specified by:
toString in interface ContentStream
Overrides:
toString in class EncryptedDataStream
Parameters:
detailed - - whether or not to give detailed information
Returns:
the string representation

This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note).

IAIK-JCE 3.1 with IAIK-JCE CC Core 3.1, (c) 1997-2004 IAIK