public class EncryptedData extends EncryptedDataStream implements Content
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 0x00instead of:
0x04 <length> <encrypted content>The indefinite constructed 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 additionally 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
following 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.:
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);
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);
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
positive 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 0x00instead of:
0x04 <length> <encrypted content>The indefinite constructed 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).
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:
EncryptedDataStream encrypted_data = new EncryptedDataStream(encoded_stream);
EncryptedContentInfoStream eci = (EncryptedContentInfoStream) encrypted_data .getEncryptedContentInfo(); System.out.println("Content type: " + eci.getContentType().getName()); System.out.println("Content encryption algorithm: " + eci.getContentEncryptionAlgorithm().getName());
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.
byte[] content = encrypted_data.getContent();
EncryptedContentInfo
block_size, version
Modifier | Constructor and Description |
---|---|
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(java.io.InputStream is)
Creates a new EncryptedData where the DER encoded data is read from the
given InputStream.
|
Modifier and Type | Method and Description |
---|---|
void |
decode(ASN1Object obj)
Decodes the given EncryptedData ASN1 object.
|
void |
decode(java.io.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.
|
java.lang.Object |
getEncryptedContentInfo()
Returns the encrypted content info of this
EncryptedData
object. |
java.io.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. |
java.lang.String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about
this
EncryptedData object. |
getBlockSize, getContentType, getVersion, setBlockSize, setupCipher, toASN1Object, toString, writeTo, writeTo
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getBlockSize, getContentType, setBlockSize, toASN1Object
protected EncryptedData()
public EncryptedData(EncryptedContentInfo encryptedContentInfo)
encryptedContentInfo
- the already created encrypted content infopublic EncryptedData(byte[] 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.
data
- the byte array containing the data to encryptpublic EncryptedData(ASN1Object obj) throws PKCSParsingException
The ASN1Object supplied to this constructor represents an already existing
EncryptedData
object that may have been created by calling
toASN1Object
.
obj
- the ASN1Object representing an already existing EncryptedData
object.PKCSParsingException
- if an error occurs when parsing the given ASN1Objectpublic EncryptedData(java.io.InputStream is) throws java.io.IOException, PKCSParsingException
is
- the InputStream holding a DER encoded PKCS#7 EncryptedData objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic void decode(ASN1Object obj) throws PKCSParsingException
decode
in interface Content
obj
- the ASN1Object representing an already existing EncryptedData
objectPKCSParsingException
- if an error occurs when parsing the given ASN1Objectpublic void decode(java.io.InputStream is) throws java.io.IOException, PKCSParsingException
DerInputStream
, internally a DerInputStream is created before parsing the
data.decode
in interface ContentStream
decode
in class EncryptedDataStream
is
- the InputStream holding a DER encoded PKCS#7 EncryptedData objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic void setupCipher(AlgorithmID contentEA, char[] password, int iterationCount) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
EncryptedData
object by means of the EncryptedData(byte[])
constructor. 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.
setupCipher
in class EncryptedDataStream
contentEA
- the PBE-algorithm to be usedpassword
- the passworditerationCount
- the iteration count for key derivationjava.security.NoSuchAlgorithmException
- if the algorithm is not supportedjava.security.InvalidKeyException
- if the key cannot be derived from the passwordpublic void setupCipher(char[] password) throws java.security.NoSuchAlgorithmException, java.security.InvalidAlgorithmParameterException, java.security.spec.InvalidParameterSpecException, java.security.InvalidKeyException
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.
setupCipher
in class EncryptedDataStream
password
- the passwordjava.security.NoSuchAlgorithmException
- if the algorithm is not supportedjava.security.InvalidKeyException
- if the key cannot be derived from the passwordjava.security.InvalidAlgorithmParameterException
- if the parameters cannot be retrieved from the algorithm IDjava.security.spec.InvalidParameterSpecException
- if the parameters cannot be set uppublic java.io.InputStream getInputStream()
The returned content depends on whether creating a new EncryptedData or parsing an existing one:
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
arbitrarily often; it only returns a ByteArrayInputStream that is
initialized with the content bytes.getInputStream
in class EncryptedDataStream
public byte[] getContent()
The returned content depends on whether creating a new EncryptedData or parsing an existing one:
protected ASN1Object toASN1Object(int blockSize) throws PKCSException
EncryptedData
as ASN1Object where a
constructed OCTET STRING is used for encoding the encrypted content.toASN1Object
in class EncryptedDataStream
blockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if
positiveEncryptedData
as ASN1ObjectPKCSException
- if the ASN1Object could not be createdpublic java.lang.Object getEncryptedContentInfo()
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();
getEncryptedContentInfo
in class EncryptedDataStream
public byte[] getEncoded() throws PKCSException
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.PKCSException
- if an error occurs during the encoding procedurepublic java.lang.String toString(boolean detailed)
EncryptedData
object.toString
in interface ContentStream
toString
in class EncryptedDataStream
detailed
- - whether or not to give detailed information