|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object iaik.cms.EncryptedDataStream
public class EncryptedDataStream
This class represents the stream-supporting implementation 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 EncryptedDataStream
instance
the encrypted content has to be supplied as EncryptedContentInfoStream
object.
Example:
//create a EncryptedContentInfoStream for the data to be encrypted, supplied from an input stream:
InputStream dataStream = ...;
EncryptedContentInfoStream eci = new EncryptedContentInfoStream(ObjectID.cms_data, dataStream);
//generate secret key and set up the cipher for encryption:
SecretKey key = eci.setupCipher((AlgorithmID)AlgorithmID.aes256_CBC.clone());
//create an EncryptedDataStream for the EncryptedContentInfoStream:
EncryptedDataStream encrypted_data = new EncryptedDataStream(eci);
//DER encode the EncryptedDataStream
structure and write the encoding to an
//output stream:
OutputStream encoded_stream = ...;
int blockSize = ...;
encrypted_data.writeTo(encoded_stream, blockSize);
If a positive blocksize is specified, the encrypted content of the inherent
EncryptedContentInfoStream 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 for properly handling large amounts of data.
Decrypting goes the reverse way: From the DER encoded encryptedData
a new EncryptedDataStream
is created and parsed for the inherent
EncryptedContentInfoStream
. From the EncryptedContentInfoStream
the encrypted content is obtained and decrypted using the same secret key:
EncryptedDataStream encryptedData = new EncryptedDataStream(encoded_stream); EncryptedContentInfoStream eci = (EncryptedContentInfoStream)encryptedData.getEncryptedContentInfo(); //setup the cipher for decryption using the right secret key: eci.setupCipher(key); //get and read the data thereby actually performing the decryption InputStream data_is = eci.getInputStream(); byte[] buf = new byte[2048]; int r; while ((r = data_is.read(buf)) > 0) { // do something useful }
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 CMS 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 EncryptedContentInfoStream
even when doing a PBE encryption.
If you want to use PBE encryption but not creating an EncryptedContentInfoStream
by yourself you first have to supply the data to be read from an
input stream, subsequently setup the cipher for PBE-encryption and finally call
a writeTo
method for encoding the EncryptedData object to a stream:
EncryptedDataStream(InputStream is, int blockSize)
constructor for creating
a new EncryptedDataStream
object and supplying the data to be
encrypted from an inputstream. You optionally may define a particular
blockSize
value for splitting the encoding of the encrypted
content:
//the data to be encrypted supplied from an input stream: InputStream dataStream = ...; // the block size: int blockSize = ...; EncryptedDataStream encrypted_data = new EncryptedDataStream(dataStream, blockSize);
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);
writeTo
method for BER encoding the
EncryptedData object and writing it to an output stream. If not yet done you optionally
may specify a particular block size for splitting the encoding of encrypted content.
int blockSize = ...; OutputStream encoded_stream = ...; encrypted_data.writeTo(encoded_stream, blockSize);respectively
encryptped_data.writeTo(encoded_stream);It is recommended to use a positive block size value, because it is the intended purpose of this stream-supporting EncryptedData implementation to handle large amounts of data. When no block size is specified whole the encrypted content is encoded as primitive definite octet string, which advantageously may be done when using the non-stream supporting
EncryptedData
implementation.
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.
EncryptedDataStream(InputStream is)
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:
InputStream encoded_stream = ...; EncryptedDataStream encrypted_data = new EncryptedData(encoded_stream);
EncryptedContentInfoStream eci = 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 non-stream supporting
EncryptedData
class where the encrypted-content decryption
already is performed inside the setupCipher
method, the cipher
will be only initialized for decryption in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream
method. So do not call
getInputStream
before setting up the cipher!
InputStream data_is = encrypted_data.getInputStream(); byte[] buf = new byte[2048]; int r; while ((r = data_is.read(buf)) > 0) { // do something useful }
EncryptedContentInfoStream
Field Summary | |
---|---|
protected int |
blockSize_
The block size for block oriented stream encoding. |
protected EncryptedContentInfoStream |
encryptedContentInfo_
The inherent encrypted content info. |
protected SecurityProvider |
securityProvider_
The SecurityProvider responsible for cryptographic operations. |
protected Attribute[] |
unprotectedAttrs_
Optional unprotected attributes. |
protected int |
version_
The CMS version number. |
Constructor Summary | |
---|---|
protected |
EncryptedDataStream()
Default constructor for dynamic object creation in ContentInfoStream. |
|
EncryptedDataStream(EncryptedContentInfoStream encryptedContentInfo)
Creates a CMS EncryptedDataStream from an EncryptedContentInfoStream. |
|
EncryptedDataStream(java.io.InputStream is)
Creates a new EncryptedDataStream from a BER encoded EncryptedData which is read from the given InputStream. |
|
EncryptedDataStream(java.io.InputStream is,
int blockSize)
Creates a new CMS EncryptedDataStream object where the content to be encrypted is read from the supplied InputStream. |
|
EncryptedDataStream(ObjectID contentType,
java.io.InputStream is,
int blockSize)
Creates a new CMS EncryptedDataStream object where the content to be encrypted is read from the supplied InputStream. |
Method Summary | |
---|---|
void |
decode(java.io.InputStream is)
Reads and decodes an encoded EncryptedDataStream from an input stream. |
int |
getBlockSize()
Gets the block size defining the length of each definite primitive encoded octet string component. |
ObjectID |
getContentType()
Returns the content type this class implements. |
EncryptedContentInfoStream |
getEncryptedContentInfo()
Returns the encrypted content info of this EncryptedDataStream
object. |
java.io.InputStream |
getInputStream()
Returns an InputStream from where the decrypted data can be read. |
SecurityProvider |
getSecurityProvider()
Gets the SecurityProvider installed for this EncryptedDataStream. |
Attribute |
getUnprotectedAttribute(ObjectID oid)
Returns the first unprotected attribute matching to the given ObjectID, if included in this EncryptedData object. |
Attribute[] |
getUnprotectedAttributes()
Gets the unprotected attributes included in this EnvelopedData. |
int |
getVersion()
Returns the syntax version number. |
void |
notifyEOF()
This method implements the EOFListener interface for performing the final decoding. |
void |
setBlockSize(int blockSize)
Sets the block size for defining the length of each definite primitive encoded octet string component. |
void |
setInputStream(java.io.InputStream is)
Sets the input stream that supplies the content data to be encrypted. |
void |
setSecurityProvider(SecurityProvider securityProvider)
Sets the SecurityProvider for this EncryptedDataStream. |
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. |
void |
setupCipher(char[] password)
Uses the given password to setup the cipher for decrypting the content. |
void |
setupCipher(java.security.Key key)
Uses the given key to setup the cipher for decrypting the content. |
ASN1Object |
toASN1Object()
Returns this CMS EnvelopedDataStream as ASN1Object. |
protected ASN1Object |
toASN1Object(int blockSize)
Returns this CMS EncryptedData as ASN1Object. |
java.lang.String |
toString()
Returns a string giving some information about this EncryptedDataStream object. |
java.lang.String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this EncryptedDataStream object. |
void |
writeTo(java.io.OutputStream os)
BER encodes and writes this EnvelopedData to the supplied output stream. |
void |
writeTo(java.io.OutputStream os,
int blockSize)
Writes this EncryptedData encoded to the supplied output stream. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
protected int version_
protected int blockSize_
protected EncryptedContentInfoStream encryptedContentInfo_
protected Attribute[] unprotectedAttrs_
protected SecurityProvider securityProvider_
Constructor Detail |
---|
protected EncryptedDataStream()
public EncryptedDataStream(EncryptedContentInfoStream encryptedContentInfo)
encryptedContentInfo
- the already created encrypted content infopublic EncryptedDataStream(java.io.InputStream is, int blockSize)
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 EncryptedDataStream(EncryptedContentInfoStream)
constructor shall be used to be supplied with a precomputed EncryptedContentInfo.
Consult the EncryptedContentInfoStream
class documentation for more information about
EncryptedContentInfo handling.
is
- the InputStream containing the data to encryptblockSize
- for defining the encoding scheme and setting the octet
string component length, if positivepublic EncryptedDataStream(ObjectID contentType, java.io.InputStream is, int blockSize)
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 EncryptedDataStream(EncryptedContentInfoStream)
constructor shall be used to be supplied with a precomputed EncryptedContentInfo.
Consult the EncryptedContentInfoStream
class documentation for more information about
EncryptedContentInfo handling.
contentType
- the content type of the data to be encryptedis
- the InputStream containing the data to encryptblockSize
- for defining the encoding scheme and setting the octet
string component length, if positivepublic EncryptedDataStream(java.io.InputStream is) throws java.io.IOException, CMSParsingException
is
- the InputStream holding a BER encoded EncryptedDataStream object
java.io.IOException
- if an I/O error occurs during reading from the InputStream
CMSParsingException
- if an error occurs while parsing the objectMethod Detail |
---|
public void setSecurityProvider(SecurityProvider securityProvider)
This method allows to explicitly set a SecurityProvider for this EncryptedDataStream. 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:
getPBEKey
to convert a password into a SecretKey object
getInputStreamCipherEngine
methods to get an InputStreamCipherEngine
for stream based content en/decryption as used by the inherent EncryptedContentInfoStream
getByteArrayCipherEngine
methods to get a ByteArrayCipherEngine
for content en/decryption for non-stream EncryptedData
objects
generateKey
to generate the symmetric content encryption key as used by the inherent EncryptedContentInfo
getAlgorithmParameters
to parse algorithm parameters from an AlgorithmID as used by the inherent EncryptedContentInfo
securityProvider
- the SecurityProvider to be setpublic SecurityProvider getSecurityProvider()
This class uses the following method(s) of the SecurityProvider
, which may be overriden by an application, if required:
getPBEKey
to convert a password into a SecretKey object
getInputStreamCipherEngine
methods to get an InputStreamCipherEngine
for stream based content en/decryption as used by the inherent EncryptedContentInfoStream
getByteArrayCipherEngine
methods to get a ByteArrayCipherEngine
for content en/decryption for non-stream EncryptedData
objects
generateKey
to generate the symmetric content encryption key as used by the inherent EncryptedContentInfo
getAlgorithmParameters
to parse algorithm parameters from an AlgorithmID as used by the inherent EncryptedContentInfo
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.
null
if
this object does not have its own SecurityProviderpublic void setBlockSize(int blockSize)
blockSize
is smaller or equal to zero the
whole data is encoded as definite primitive octet string.
setBlockSize
in interface ContentStream
blockSize
- for defining the encoding scheme and setting the octet
string component length, if positivepublic int getBlockSize()
blockSize
is smaller or equal to zero the
whole data is encoded as definite primitive octet string.
getBlockSize
in interface ContentStream
public void decode(java.io.InputStream is) throws java.io.IOException, CMSParsingException
decode
in interface ContentStream
is
- the InputStream supplying an encoded EncryptedData object
java.io.IOException
- if an I/O error occurs during reading from the InputStream
CMSParsingException
- if an error occurs while parsing the objectpublic void setupCipher(AlgorithmID contentEA, char[] password) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
EncryptedDataStream
object by means of the EncryptedDataStream(InputStream is, int blockSize)
constructor.
The content encryption actually is performed during the encoding when
writing this EncyrptedData to a stream by calling the writeTo
method. So it is important to setup the cipher before writing to
the stream!
setupCipher(AlgorithmID, char[], int)
.
contentEA
- the PBE-algorithm to be usedpassword
- the password
java.security.NoSuchAlgorithmException
- if the algorithm is not supported
java.security.InvalidKeyException
- if the key cannot be derived from the passwordpublic void setupCipher(AlgorithmID contentEA, char[] password, int iterationCount) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
EncryptedDataStream
object by means of the EncryptedDataStream(InputStream is, int blockSize)
constructor.
The content encryption actually is performed during the encoding when
writing this EncyrptedData to a stream by calling the writeTo
method. So 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 2000.
contentEA
- the PBE-algorithm to be usedpassword
- the passworditerationCount
- the iteration count for key derivation
java.security.NoSuchAlgorithmException
- if the algorithm is not supported
java.security.InvalidKeyException
- if the key cannot be derived from the passwordpublic void setupCipher(AlgorithmID contentEA, java.security.Key key, java.security.spec.AlgorithmParameterSpec paramSpec) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
EncryptedDataStream
object by means of the EncryptedDataStream(InputStream is, int blockSize)
constructor.
The content encryption actually is performed during the encoding when
writing this EncyrptedData to a stream by calling the writeTo
method. So it is important to setup the cipher before writing to
the stream!
contentEA
- the content encryption algorithm to be usedkey
- the content encryption key to be usedparamSpec
- any required parameters (maybe null
if no parameters
are required or you want to let the cipher create the paramters
(e.g. iv)
java.security.NoSuchAlgorithmException
- if the algorithm is not supported
java.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 non-stream supporting EncryptedData
class where the encrypted-content decryption
already is performed inside the setupCipher
method, the cipher
will be only initialized for decrypting in this class. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream
method. So do not call
getInputStream
before setting up the cipher!
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 EncryptedContentInfoStream
class has to be used to setup the cipher for content decryption.
password
- the password
java.security.NoSuchAlgorithmException
- if the algorithm is not supported
java.security.InvalidKeyException
- if the key cannot be derived from the password
java.security.InvalidAlgorithmParameterException
- if the paramters cannot be retrieved
from the algorithm ID
java.security.spec.InvalidParameterSpecException
- if the paramters cannot be set uppublic void setupCipher(java.security.Key key) throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
Unlike the non-stream supporting EncryptedData
class where the encrypted-content decryption
already is performed inside the setupCipher
method, the cipher
will be only initialized for decrypting in this method. The encrypted-content
decryption actually is done during reading the data obtained by calling the
getInputStream
method. So do not call
getInputStream
before setting up the cipher!
key
- the key to be used for decrypting the encrypted content
java.security.NoSuchAlgorithmException
- if the algorithm is not supported
java.security.InvalidKeyException
- if the cipher cannot be setup for decryption
with the given keypublic void setUnprotectedAttributes(Attribute[] attributes)
attributes
- the unprotected attributes to be setpublic ObjectID getContentType()
getContentType
in interface ContentStream
ObjectID.cms_encryptedData
public int getVersion()
public Attribute[] getUnprotectedAttributes()
public Attribute getUnprotectedAttribute(ObjectID oid)
null
if there is no attribute for the given OID.public java.io.InputStream getInputStream()
When having created a new EncryptedDataStream
object to
be encoded to a stream, this method should not be utilized at all, since
the stream automatically will be read during performing the encoding
which is done when calling a writeTo
method).
When having decoded and parsed a received EnvelopedDataStream
object comimg from some stream, this method may be used for obtaining the raw (decrypted) data
after having setup the cipher (if PBE-encryption is used).
public void setInputStream(java.io.InputStream is)
is
- the input stream holding the content data to encryptpublic ASN1Object toASN1Object() throws CMSException
toASN1Object
in interface ContentStream
EnvelopedData
as ASN1Object.
CMSException
- if the ASN1Object could not be createdprotected ASN1Object toASN1Object(int blockSize) throws CMSException
EncryptedData
as ASN1Object.
blockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positive
EncryptedData
as ASN1Object
CMSException
- if the ASN1Object could not be createdpublic void writeTo(java.io.OutputStream os) throws java.io.IOException
os
- the output stream to which this EnvelopedData shall be written
java.io.IOException
public void writeTo(java.io.OutputStream os, int blockSize) throws java.io.IOException
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 for properly handling large amounts of data.
os
- the output stream to which this SignedData shall be writtenblockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positive
java.io.IOException
- if an error occurs during writing the objectpublic void notifyEOF() throws java.io.IOException
iaik.utils.NotifyEOFInputStream
is wrapped around this content data stream
for indicating that the parsing procedure is to be notified when the stream actually
has been read. At that point, the programm exceuting automatically jumps to the
notifyEOF
method for finishing the decoding by parsing the
remaining unprotected attributes, if present.
notifyEOF
in interface EOFListener
java.io.IOException
- if an error occurs while parsing the streampublic EncryptedContentInfoStream getEncryptedContentInfo()
EncryptedDataStream
object.
public java.lang.String toString()
EncryptedDataStream
object.
toString
in class java.lang.Object
public java.lang.String toString(boolean detailed)
EncryptedDataStream
object.
toString
in interface ContentStream
detailed
- - whether or not to give detailed information
|
This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note). | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |