|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--iaik.pkcs.pkcs7.EnvelopedDataStream | +--iaik.pkcs.pkcs7.EnvelopedData
This class represents the non-stream supporting implementation of the PKCS#7
content type EnvelopedData
.
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 EnvelopedData
content type is
defined as:
envelopedData OBJECT IDENTIFIER ::= { pkcs-7 3 }
which corresponds to the OID string "1.2.840.1.113549.1.7.3".
The PKCS#7
Cryptographic Message Standard specifies the EnvelopedData
content type for providing a syntax for building digital envelopes. Content
of any type may be enveloped for any number of recipients in parallel. For
each recipient, a commonly at random generated content-encryption key is
encrypted with the particular recipientīs public key and - together with
recipient-specific information - collected into a RecipientInfo
value. The content is encrypted with the content-encryption key giving a
EncryptedContent
value, which - in combination with a
recipient-specific encrypted content-encryption key - forms the digital
envelope for each particular recipient. All RecipientInfo
values are collected together with the encrypted content into an
EnvelopedData
value to be sent to each intended recipient.
This class implements the EnvelopedData
structure resulting from
the last step described above. The EnvelopedData
type is defined
as ASN.1 SEQUENCE type containing the following components (see PKCS#7 specification,
Version 1.5):
EnvelopedData ::= SEQUENCE { version Version, recipientInfos RecipientInfos, encryptedContentInfo EncryptedContentInfo }
RecipientInfos ::= SET OF RecipientInfo
EncryptedContentInfo ::= SEQUENCE { contentType ContentType, contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
EncryptedContent ::= OCTET STRING
The recipientInfos
field is a non-empty collection of
per-recipient information. The encryptedContentInfo
field
specifies the type of the content being enveloped, the content-encryption
algorithm (the same for all recipients) 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.
A recipient, when receiving the EnvelopedData
message,
decrypts the corresponding encrypted content-encryption key with his/her
private key for subsequently decrypting the encrypted content using the
content-encryption key just recovered. The recipient's private key is
referenced by an issuer distinguished name and an issuer-specific serial
number that uniquely identify the certificate for the corresponding public
key.
For more information consult the RSA PKCS#7 specification.
When creating a new EnvelopedData
object for the data to be enveloped
the symmetric algorithm has to be specified to be used for content-encryption. After setting
the recipients, the EnvelopedData object may be prepared for transmission by transforming
it into an ASN1Object or immediately encoding it, e.g.:
EnvelopedData(byte[] content, AlgorithmID contentEA)
constructor:
//the data to be enveloped: byte[] data = ...; //use TripleDES in CBC mode for encrypting the content EnvelopedData enveloped_data = new EnvelopedData(data, AlgorithmID.des_EDE3_CBC);
RecipientInfo
object, and add all RecipientInfos to the EnvelopedData
structure by calling the setRecipientInfos
method, e.g.
(assuming to add two recipients with corresponding certificates cert1
and
cert2
; currently only the PKCS#1 rsaEncryption is supported as key-
encryption algorithm):
RecipientInfo[] recipients = new RecipientInfo[2]; recipients[0] = new RecipientInfo(cert1, AlgorithmID.rsaEncryption); recipients[1] = new RecipientInfo(cert2, AlgorithmID.rsaEncryption); enveloped_data.setRecipientInfos(recipients);
ASN1Object obj = enveloped_data.toASN1Object();respectively
byte[] encoding = enveloped_data.getEncoding();For forcing a constructed, blocksize oriented encoding, alternatively you may use the corresponding
writeTo
method of the parent EnvelopedDataStream
class.
EnvelopedData(ASN1Object obj)
constructor for parsing the internal structure. Before getting the recovered content by means of the
getContent
method, the cipher has to be
initialized for decryption with the particular recipientīs private key by calling the
setupCipher
method:
ASN1Object obj = DerCoder.decode(encoding);
EnvelopedData enveloped_data = new EnvelopedData(obj);
EncryptedContentInfo eci = (EncryptedContentInfo)enveloped_data.getEncryptedContentInfo(); System.out.println("Content type: "+eci.getContentType().getName()); System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
RecipientInfo[] recipients = enveloped_data.getRecipientInfos(); System.out.pritnln("Included RecipientInfos:"); for (int i=0; i < recipients.length; i++) { System.out.print("Recipient "+(i+1)+":"); System.out.println(recipients[i].getIssuerAndSerialNumber()); }
//setup cipher for recipient 1: int recipientInfoIndex = 0; enveloped_data.setupCipher(privateKey, recipientInfoIndex);Unlike the stream supporting
EnvelopedDataStream
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 = enveloped_data.getContent();
PKCS#7v1.6 Support:
===================
This class also may be used for creating/parsing EnvelopedData objects of version 1.6 as
used by the SET protocol. Main differences between v1.5 and v1.6 are the content encryption
(v1.6 encrypts the whole content encoding and therefore may be unsuitable
for handling large amounts of data) and the encoding of SET OF structures which is
replaced by SEQUENCE OF in PKCS#7v1.6.
For creating a v1.6 EnvelopedData object you only have to set the version number (1 for
indicating PKCS#7v1.6) when creating
an EnvelopedData object:
byte[] content = ...; AlgorithmID contentEA = ...; int keyLength = ...; // version number 1 indicates PKCS#7v1.6 int version = 1; EnvelopedData envelopedData = new EnvelopedData(content, contentEA, keyLength, version); ...On the receiving end you can use this class in the same way as described above for parsing and decrypting the content of a PKCS#7v1.5 or v1.6 EnvelopedData object. Since PKCS#7v1.6 is unsuitable for stream handling, the stream based class
EnvelopedDataStream
does not support PKCS#7v1.6.
RecipientInfo
,
EncryptedContentInfo
Fields inherited from class iaik.pkcs.pkcs7.EnvelopedDataStream |
block_size, encrypted_content_info, recipient_infos, symmetric_key, version |
Constructor Summary | |
protected |
EnvelopedData()
Default constructor for dynamic object creation in ContentInfo. |
|
EnvelopedData(ASN1Object obj)
Creates a PKCS#7 EnvelopedData from an ASN1Object. |
|
EnvelopedData(byte[] content,
AlgorithmID contentEA)
Creates a new PKCS#7 EnvelopedData object where the raw data is supplied as byte array. |
|
EnvelopedData(byte[] content,
AlgorithmID contentEA,
int keyLength)
Creates a new PKCS#7 EnvelopedData object where the raw data is supplied as byte array. |
|
EnvelopedData(byte[] content,
AlgorithmID contentEA,
int keyLength,
int version)
Creates a new PKCS#7 EnvelopedData object where the raw data is supplied as byte array. |
|
EnvelopedData(InputStream is)
Creates a new EnvelopedData where the DER encoded data is read from the given InputStream. |
|
EnvelopedData(RecipientInfo[] recipients,
EncryptedContentInfo encryptedCI)
Constructs a PKCS#7 EnvelopedData type with an already created EncryptedContentInfo. |
|
EnvelopedData(RecipientInfo[] recipients,
EncryptedContentInfo encryptedCI,
int version)
Constructs a PKCS#7 EnvelopedData type with an already created EncryptedContentInfo. |
Method Summary | |
void |
decode(ASN1Object obj)
Decodes the given EnvelopedData ASN1 object. |
void |
decode(InputStream is)
Reads and decodes the EnvelopedData from a DerInputStream. |
byte[] |
getContent()
Returns the content as byte array. |
byte[] |
getEncoded()
Returns the DER encoding of this EnvelopedData in a byte array. |
Object |
getEncryptedContentInfo()
Returns the encrypted content info included in this EnvelopedData object.
|
InputStream |
getInputStream()
Returns an InputStream for reading the content. |
void |
setupCipher(Key key)
Uses the given symmetric key to setup the cipher for decrypting the content. |
void |
setupCipher(PrivateKey recipientPrivateKey,
int recipientInfoIndex)
Uses the specified private key to setup the Cipher for decrypting the content-encryption key and subsequently using it to decrypt the encrypted content of this
EnvelopedData object for the requesting recipient, specified by its
recipientInfoIndex .
|
protected ASN1Object |
toASN1Object(int blockSize)
Returns this EnvelopedData as ASN1Object. |
String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this EnvelopedData object. |
Methods inherited from class iaik.pkcs.pkcs7.EnvelopedDataStream |
addRecipientInfo, getBlockSize, getContentType, getRecipientInfo, getRecipientInfos, getVersion, setBlockSize, setRecipientInfos, 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 |
protected EnvelopedData()
public EnvelopedData(byte[] content, AlgorithmID contentEA) throws NoSuchAlgorithmException
When using this constructor, automatically a symmetric key for content
encryption is generated. For that reason this constructor shall not be used
in situations where the desired content encryption algorithm requires a
specific key/parameter handling. In such cases the EnvelopedData(RecipientInfo[], EncryptedContentInfo)
constructor shall be used to be supplied with precomputed RcipientInfos
and EncryptedContentInfo. Consult the EncryptedContentInfo(Stream)
class documentation for more information about
special key/parameter handling.
content
- the byte array containing the data to envelopecontentEA
- the content encryption algorithm for encrypting the contentNoSuchAlgorithmException
- if there is no implementation for the specified algorithmpublic EnvelopedData(byte[] content, AlgorithmID contentEA, int keyLength) throws NoSuchAlgorithmException
When using this constructor, automatically a symmetric key for content
encryption is generated. If the specified content encryption algorithm supports
variable key lengths, a particular key length may be set by means of the
keyLength
parameter.
If no length is specified, the defined default key length will be used. If the
algorithm only works with keys of fixed-size length, the keyLength parameter
may be set to -1 or the EnvelopedData(byte[] content, AlgorithmID contentEA)
constructor may be used.
This constructor shall not be used
in situations where the desired content encryption algorithm requires a
specific key/parameter handling. In such cases the EnvelopedData(RecipientInfo[], EncryptedContentInfo)
constructor shall be used to be supplied with precomputed RcipientInfos
and EncryptedContentInfo. Consult the EncryptedContentInfo(Stream)
class documentation for more information about
special key/parameter handling.
content
- the byte array containing the data to envelopecontentEA
- the content encryption algorithm for encrypting the contentkeyLength
- the key length that may be set when using a content
encryption algorithm that supports variable key lengthsNoSuchAlgorithmException
- if there is no implementation for the specified algorithmpublic EnvelopedData(byte[] content, AlgorithmID contentEA, int keyLength, int version) throws NoSuchAlgorithmException
When using this constructor, automatically a symmetric key for content
encryption is generated. If the specified content encryption algorithm supports
variable key lengths, a particular key length may be set by means of the
keyLength
parameter.
If no length is specified, the defined default key length will be used. If the
algorithm only works with keys of fixed-size length, the keyLength parameter
may be set to -1 or the EnvelopedData(byte[] content, AlgorithmID contentEA)
constructor may be used.
This constructor shall not be used
in situations where the desired content encryption algorithm requires a
specific key/parameter handling. In such cases the EnvelopedData(RecipientInfo[], EncryptedContentInfo)
constructor shall be used to be supplied with precomputed RcipientInfos
and EncryptedContentInfo. Consult the EncryptedContentInfo(Stream)
class documentation for more information about
special key/parameter handling.
This constructor may be used for creating an v1.6 EnvelopedData message, where the version number (1) has to be supplied for indicating to encrypt the content encoding.
content
- the byte array containing the data to envelopecontentEA
- the content encryption algorithm for encrypting the contentkeyLength
- the key length that may be set when using a content
encryption algorithm that supports variable key lengthsversion
- either 0 (indicating a PKCS#7v1.5 EnvelopedData) or
1 (indicating a PKCS#71.6 EnvelopedData); default is 0.NoSuchAlgorithmException
- if there is no implementation for the specified algorithmpublic EnvelopedData(RecipientInfo[] recipients, EncryptedContentInfo encryptedCI)
RecipientInfo
specifies a collection of
per-recipient information, and the given EncryptedContentInfo
supplies the already encrypted content.recipients
- information about the recipientsencryptedCI
- the encrypted content infopublic EnvelopedData(RecipientInfo[] recipients, EncryptedContentInfo encryptedCI, int version)
The given array of RecipientInfo
specifies a collection of
per-recipient information, and the given EncryptedContentInfo
supplies the already encrypted content.
This constructor may be used for creating an v1.6 EnvelopedData message, where the version number (1) has to be supplied for indicating that supplied EncryptedContentInfo has encrypted the content encoding.
recipients
- information about the recipientsencryptedCI
- the encrypted content infoversion
- either 0 (indicating a PKCS#7v1.5 EnvelopedData) or
1 (indicating a PKCS#71.6 EnvelopedData); default is 0.public EnvelopedData(ASN1Object obj) throws PKCSParsingException
EnvelopedData
object that may have
been created by calling toASN1Object
.
Use the EnvelopedData(byte[] content, AlgorithmID contentEA)
constructor
for supplying the content to be enveloped when creating an
EnvelopedData
object.
obj
- the PKCS#7 EnvelopedData
as ASN1ObjectPKCSParsingException
- if the object can not be parsedpublic EnvelopedData(InputStream is) throws PKCSParsingException, IOException
is
- the InputStream holding a DER encoded PKCS#7 EnvelopedData objectIOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectMethod Detail |
public void decode(ASN1Object obj) throws PKCSParsingException
decode
in interface Content
obj
- the ASN1Object representing an already exisiting EnvelopedData objectPKCSParsingException
- if an error occurs when parsing the given ASN1Objectpublic void decode(InputStream is) throws IOException, PKCSParsingException
DerInputStream
,
internally a DerInputStream is created before parsing the data.decode
in interface ContentStream
decode
in class EnvelopedDataStream
is
- the InputStream holding a DER encoded PKCS#7 EnvelopedData objectIOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic void setupCipher(PrivateKey recipientPrivateKey, int recipientInfoIndex) throws PKCSException, NoSuchAlgorithmException, InvalidKeyException
EnvelopedData
object for the requesting recipient, specified by its
recipientInfoIndex
.
This method first uses the given private key for decrypting the encrypted
temporary symmetric key obtained from the corresponding RecipientInfo
structure, and subsequently uses this key for decrypting the encrypted content.
Unlike the stream supporting EnvelopedDataStream
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
encryption AlgorithmID contains IV parameters encoded as an OCTET_STRING. When
the algorithmID contains parameters of other type (e.g. S/MIME RC2-CBC parameters)
they have to be decoded separatly, and the setupCipher(Key key, AlgorithmParameterSpec)
method of the EncryptedContentInfo
class has to be used to setup the cipher for content decryption, e.g.:
//get the ECI from the enveloped data: EncryptedContentInfo eci = (EncryptedContentInfo)enveloped_data.getEncryptedContentInfo(); // get the recipient infos RecipientInfo[] recipients = enveloped_data.getRecipientInfos(); // use the specific recipientīs private key for decrypting the required // symmetric content encryption key, e.g.: SecretKey secretKey = recipient_infos[0].decryptKey(recipientPrivateKey) //get the content encryption algorithm: AlgorithmID contentEA = eci.getContentEncryptionAlgorithm(); // get the parameters as SEQUENCE SEQUENCE seq = (SEQUENCE)contentEA.getParameter(); // the iv is the second component OCTET_STRING oct = (OCTET_STRING)seq.getComponentAt(1); // create an IvParameterSpec: IvParameterSpec ivSpec = new IvParameterSpec(oct.getValue()); //now setup the cipher with previously decrypted recipient key amd params eci.setupCipher(secretKey, ivSpec); //get the recovered raw data: byte[] data = EncryptedContentInfo.getContent();
setupCipher
in class EnvelopedDataStream
recipientPrivateKey
- the private key of one recipient specified in
a RecipientInfo objectrecipientInfoIndex
- specifies which RecipientInfo the private key belongs toPKCSException
- if there occurs an error while decrypting the dataNoSuchAlgorithmException
- if there is no implementation of the content-encryption algorithmInvalidKeyException
- if the specified private key is not validpublic void setupCipher(Key key) throws PKCSException, NoSuchAlgorithmException, InvalidKeyException
Unlike the stream supporting EnvelopedDataStream
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
encryption AlgorithmID contains IV parameters encoded as an OCTET_STRING. When
the algorithmID contains parameters of other type (e.g. S/MIME RC2-CBC parameters)
they have to be decoded separatly, and the setupCipher(Key key, AlgorithmParameterSpec)
method of the EncryptedContentInfo
class has to be used to setup the cipher for content decryption, e.g.:
//get the ECI from the enveloped data: EncryptedContentInfo eci = (EncryptedContentInfo)enveloped_data.getEncryptedContentInfo(); //get the content encryption algorithm: AlgorithmID contentEA = eci.getContentEncryptionAlgorithm(); // get the parameters as SEQUENCE SEQUENCE seq = (SEQUENCE)contentEA.getParameter(); // the iv is the second component OCTET_STRING oct = (OCTET_STRING)seq.getComponentAt(1); // create an IvParameterSpec: IvParameterSpec ivSpec = new IvParameterSpec(oct.getValue()); //now setup the cipher with previously decrypted recipient key amd params eci.setupCipher(secretKey, ivSpec); //get the recovered raw data: byte[] data = EncryptedContentInfo.getContent();
setupCipher
in class EnvelopedDataStream
key
- the temporary symmetric key that has been used to encrypt the content,
and now is used for decrypting it againPKCSException
- if there occurs an error while decrypting the dataNoSuchAlgorithmException
- if there is no implementation for the content-encryption algorithmInvalidKeyException
- if the specified private key is not validpublic InputStream getInputStream()
The returned content depends on whether creating a new EnvelopedData or parsing an existing one:
getInputStream
method
of the parent EnvelopedDataStream
class for returning the content of this EnvelopedData
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 EnvelopedDataStream
class, this method may be called arbitrarly
often; it only returns a ByteArrayInputStream that is initialized with the content
bytes.getInputStream
in class EnvelopedDataStream
public byte[] getContent()
The returned content depends on whether creating a new EnvelopedData or parsing an existing one:
public Object getEncryptedContentInfo()
EnvelopedData
object.
When calling this method for obtaining the inherent EncryptedContentInfo
an explicit cast to EncryptedContentInfo
has to be made:
EncryptedContentInfo eci = (EncryptedContentInfo)enveloped_data.getEncryptedContentInfo();
getEncryptedContentInfo
in class EnvelopedDataStream
protected ASN1Object toASN1Object(int blockSize) throws PKCSException
toASN1Object
in class EnvelopedDataStream
blockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positiveEnvelopedData
as ASN1ObjectPKCSException
- if the ASN1Object could not be createdpublic byte[] getEncoded() throws PKCSException
public String toString(boolean detailed)
EnvelopedData
object.toString
in interface ContentStream
toString
in class EnvelopedDataStream
detailed
- - whether or not to give detailed information
|
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). | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |