public class EnvelopedData extends EnvelopedDataStream implements Content
EnvelopedData.
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 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 CMS
Cryptographic Message Syntax (RFC 2630) 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 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 RFC 2630:
EnvelopedData ::= SEQUENCE {
version CMSVersion,
originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
recipientInfos RecipientInfos,
encryptedContentInfo EncryptedContentInfo
unprotectedAttrs [1] IMPLICIT UnptotectedAttributes OPTIONAL }
OriginatorInfo ::= SEQUENCE {
certs [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL }
RecipientInfos ::= SET OF RecipientInfo
EncryptedContentInfo ::= SEQUENCE {
contentType ContentType,
contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
EncryptedContent ::= OCTET STRING
UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
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.
CMS provides three alternatives for encrypting the content depending
on the key management algorithm used to protect the content encryption
key for a specific recipient:
KeyTransRecipientInfo for the public key of the recipient´s
certificate, identified by IssuerAndSerialNumber. CMS recommends to use RSA for encrypting
the content encryption key.
KeyAgreeRecipientInfo may transfer the encrypted content
encryption key to one or more recipient using the same key
agreement algorithm and domain parameters for that algorithm.
CMS recommends to use ephemeral-static DH or ECDH with an
ephemeral sender key.
KEKRecipientInfo using a CMS key wrap algorithm like
Triple-DES key wrap or RC2 key wrap.
originatorInfo field may be used to include certificate/crl
information about the originator if required by the key managemant ptotocol.
unprotectedAttrs optionally may provide some attributes that are
not encrypted.
A recipient, when receiving the EnvelopedData message,
decrypts the corresponding encrypted content-encryption key with his/her
key according the right key management protocol for subsequently decrypting the
encrypted content using the content-encryption key just recovered. The recipient's
key is referenced by proper KeyIdentifier included
in the corresponding RecipientInfo object.
See RFC 2630 for more information.
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. Calling
this constructor internally will generate the temporary content-encryption key for the
specified content-encryption algorithm. If using a content-encryption algorithm
allowing keys of different size, you may specify the key length by using the
EnvelopedData(byte[] content, AlgorithmID contentEA, int keyLength)
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 of requested type (KeyTransRecipientInfo, KeyAgreeRecipientInfo,
or KEKRecipientInfo), and add all RecipientInfos
to the EnvelopedDataStream object by calling the setRecipientInfos
method, e.g. (assuming to use KeyTransRecipientInfos for two recipients with
corresponding certificates cert1 and cert2):
RecipientInfo[] recipients = new RecipientInfo[2];
recipients[0] = new KeyTransRecipientInfo(cert1, AlgorithmID.rsaEncryption);
recipients[1] = new KeyTransRecipientInfo(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) or
EnvelopedData(InputStream is) constructor for
parsing the EnvelopedData supplied as ASN1Object oder DER encoding. Before getting
the recovered content by means of the getContent method, the
cipher has to be initialized for decryption with the particular recipient´s key by
calling one of the following setupCipher methods:
setupCipher(Key recipientKey, int recipientInfoIndex):
This method can be used for decrypting the encrypted content-encryption key for
a RecipientInfo of any type; however, you must know the right index into the
recipientInfo field. The recovered content-encryption key is used
for setting up the cipher to decrypt the encrypted content.
setupCipher(Key recipientKey,
KeyIdentifier recipientKeyIdentifier): This method can be used for decrypting the
encrypted content-encryption key for a RecipientInfo of any type; the recipient is
identified by its RecipientKeyIdentifier.
The recovered content-encryption key is used for setting up the cipher to decrypt
the encrypted content.
setupCipher(Key recipientKey,
X509Certificate recipientCertificate): This method only can be used for decrypting
the encrypted content-encryption key for a RecipientInfo of type KeyTransRecipientInfo or KeyAgreeRecipientInfo; the recipient is
identified by its public key certficate. The recovered content-encryption key is used
for setting up the cipher to decrypt the encrypted content.
setupCipher(Key): In contrast to the three setupCipher
above you have to supply the already decrypted content-encryption key when setting
up the cipher for content encryption using this setupCipher method.
KeyTransRecipientInfo,
we can use any of the setupCipher methods to setup the cipher for
decrypting the encrypted content-encryption key and the encrypted content:
ByteArrayInputStream bais = new ByteArrayInputStream(encoding);
EnvelopedData enveloped_data = new EnvelopedData(is);
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]);
}
// the private key of recipient 1:
Key privateKey = ...;
//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();
blockSize_, encryptedContentInfo_, m_envelopedData, originatorInfo_, recipientInfos_, symmetricKey_, unprotectedAttrs_, version_| Modifier | Constructor and Description |
|---|---|
protected |
EnvelopedData()
Default constructor for dynamic object creation in ContentInfo.
|
|
EnvelopedData(ASN1Object obj)
Creates a CMS EnvelopedData from an ASN1Object.
|
|
EnvelopedData(byte[] content,
AlgorithmID contentEA)
Creates a new CMS EnvelopedData object where the raw data is supplied
as byte array.
|
|
EnvelopedData(byte[] content,
AlgorithmID contentEA,
int keyLength)
Creates a new CMS EnvelopedData object where the raw data is supplied
as byte array.
|
|
EnvelopedData(java.io.InputStream is)
Creates a new EnvelopedData where the DER encoded data
is read from the given InputStream.
|
|
EnvelopedData(ObjectID contentType,
byte[] content,
AlgorithmID contentEA)
Creates a new CMS EnvelopedData object where the raw data is supplied
as byte array.
|
|
EnvelopedData(ObjectID contentType,
byte[] content,
AlgorithmID contentEA,
int keyLength)
Creates a new CMS EnvelopedData object where the raw data is supplied
as byte array.
|
|
EnvelopedData(RecipientInfo[] recipients,
EncryptedContentInfo encryptedCI)
Constructs a CMS EnvelopedData type with an already
created EncryptedContentInfo.
|
| Modifier and Type | Method and Description |
|---|---|
void |
decode(ASN1Object obj)
Decodes the given EnvelopedData ASN1 object.
|
void |
decode(java.io.InputStream is)
Reads and decodes an encoded EnvelopedData from the given input stream.
|
byte[] |
getContent()
Returns the content as byte array.
|
byte[] |
getEncoded()
Returns the DER encoding of this EnvelopedData in a byte array.
|
protected ASN1Object |
toASN1Object(int blockSize)
Returns this EnvelopedData as ASN1Object.
|
addRecipientInfo, getBlockSize, getContentType, getEncryptedContentInfo, getInputStream, getOriginatorInfo, getRecipientInfo, getRecipientInfo, getRecipientInfos, getUnprotectedAttribute, getUnprotectedAttributes, getVersion, notifyEOF, setBlockSize, setOriginatorInfo, setRecipientInfos, setUnprotectedAttributes, setupCipher, setupCipher, setupCipher, setupCipher, setupCipher, setupCipher, toASN1Object, toString, toString, writeTo, writeToclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitgetBlockSize, getContentType, setBlockSize, toASN1Object, toStringprotected EnvelopedData()
public EnvelopedData(byte[] content,
AlgorithmID contentEA)
throws java.security.NoSuchAlgorithmException
Data.
When using this constructor, automatically a temporary symmetric key for content
encryption is generated. If using a content-encryption algorithm allowing keys
of different size, you may specify the key length by using the EnvelopedData(byte[] content, AlgorithmID contentEA, int keyLength)
constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.
content - the byte array containing the data to envelopecontentEA - the content encryption algorithm for encrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentEA) throws java.security.NoSuchAlgorithmException
When using this constructor, automatically a temporary symmetric key for content
encryption is generated. If using a content-encryption algorithm allowing keys
of different size, you may specify the key length by using the EnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentEA, int keyLength)
constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.
contentType - the content type of the content to be envelopedcontent - the byte array containing the data to envelopecontentEA - the content encryption algorithm for encrypting the contentjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedData(byte[] content,
AlgorithmID contentEA,
int keyLength)
throws java.security.NoSuchAlgorithmException
Data.
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.
Note that the supplied contentEA AlgorithmID internally is cloned.
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 lengthsjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic EnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentEA, int keyLength) throws java.security.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(ObjectID contentType, byte[] content, AlgorithmID contentEA) constructor may be used.
Note that the supplied contentEA AlgorithmID internally is cloned.
contentType - the content type of the content to be envelopedcontent - 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 lengthsjava.security.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(ASN1Object obj) throws CMSParsingException
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 EnvelopedData as ASN1ObjectCMSParsingException - if the object can not be parsedpublic EnvelopedData(java.io.InputStream is)
throws CMSParsingException,
java.io.IOException
is - the InputStream supplying a DER encoded EnvelopedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - if an error occurs while parsing the objectpublic void decode(ASN1Object obj) throws CMSParsingException
decode in interface Contentobj - the ASN1Object representing an already exisiting EnvelopedData objectCMSParsingException - if an error occurs when parsing the given ASN1Objectpublic void decode(java.io.InputStream is)
throws java.io.IOException,
CMSParsingException
decode in interface ContentStreamdecode in class EnvelopedDataStreamis - the InputStream holding a DER encoded CMS EnvelopedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - if an error occurs while parsing the objectpublic byte[] getContent()
The returned content depends on whether creating a new EnvelopedData or parsing an existing one:
protected ASN1Object toASN1Object(int blockSize) throws CMSException
toASN1Object in class EnvelopedDataStreamblockSize - the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positiveEnvelopedData as ASN1ObjectCMSException - if the ASN1Object could not be createdpublic byte[] getEncoded()
throws CMSException
CMSException