public class SMimeEncrypted extends EnvelopedDataStream
S/MIME (Secure/Multipurpose Internet Mail Extensions) specifies the application/pkcs7-mime (smime-type "enveloped-data") type for data enveloping.
The whole (prepared) MIME entity to be enveloped into a PKCS#7 object of
type EnvelopedData which subsequently is inserted into an
application/pkcs7-mime MIME entity. The smime-type parameter for
enveloped messages is "enveloped-data", the file extension is ".p7m" (see
S/MIME Version 2 Message Specification). The "Content-" headers of a sample
message would look like:
Content-Type: application/pkcs7-mime; smime-type=enveloped-data;
name="smime.p7m"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7m"
rfvbn...
This class extends the EnvelopedDataStream class of the iaik.pkcs.pkcs7
package of the IAIK-JCE toolkit for taking advantage of the stream architecture
introduced there. Following this practice, the data is prepared according
PKCS#7 by piping it through a cipher stream for performing the content
encryption. According to the
S/MIME Version 2 Message Specification, this class supports the following
content encryption algorithms:
The symmetric content encryption key is encrypted by using the rsaEncryption method as specified by PKCS#1.
The steps for creating a SMimeEncrypted object and writing it to a stream may be summarized as follows:
InputStream data_stream = ...;
AlgorithmID contentEA = AlgorithmID.des_CBC;
SMimeEncrypted sme = new SMimeEncryoted(data_stream, contentEA, -1);
This step also will create the symmetric content encryption key.
addRecipient method thereby
specfying the particular recipient´s certificate and setting the RSA
encryption method to be used for encrypting the symmetric content encryption
key with the recipient´s public key obtained from the supplied certificate, e.g.:
sme.addRecipient(recipientCert1, AlgorithmID.rsaEncryption);
sme.addRecipient(recipientCert2, AlgorithmID.rsaEncryption);
writeTo method for wrapping
the EnvelopedData object into a ContentInfo and writing it BER encoded to an
output stream thereby actually performing the content encryption by piping the
data through a cipher stream:
OutputStrem os = ...;
sme.writeTo(os);
creates
a new SMimeEncrypted object from an input stream supplying the BER encoded
message, subsequently decrypts the
encrypted symmetric content encryption key with its private key, and finally gets and reads the data holding input stream which is decrypted
during the read operation, e.g.:
InputStream enveloped_stream = ...;
SMimeEncrypted sme = new SMimeEncrypted(encrypted_stream);
//recipient has index 0
sme.decryptSymmetricKey(privateKey, 0);
//get and read the data
InputStream data_stream = sme.getInputStream();
byte[] buf = new byte[1024];
int r;
while ((r = data_is.read(buf)) > 0) {
// do something useful
}
Applications may not directly use this class for creating an enveloped S/MIME
message. They may instantiate the EncryptedContent class for sending and parsing enveloped S/MIME messsages with
help of the Java Mail architecture.
EncryptedContentblock_size, encrypted_content_info, recipient_infos, symmetric_key, version| Constructor and Description |
|---|
SMimeEncrypted(byte[] content,
AlgorithmID contentEA,
int keyLength)
Creates a new SMimeEncrypted object for the specified content
to be enveloped.
|
SMimeEncrypted(java.io.InputStream is)
Creates a new SMimeEncrypted object where the BER encoded message is read
from the given input stream.
|
SMimeEncrypted(java.io.InputStream is,
AlgorithmID contentEA,
int keyLength)
Creates a new SMimeEncrypted object where the data to be enveloped is read
from the given InputStream.
|
| Modifier and Type | Method and Description |
|---|---|
void |
addRecipient(java.security.cert.X509Certificate certificate,
AlgorithmID keyEA)
Adds one recipient to this S/MIME enveloped object.
|
void |
decode(java.io.InputStream is)
Reads and decodes the enveloped message from a DerInputStream.
|
void |
decryptSymmetricKey(KeyAndCertificateSource keyAndCertificateSource)
Locates one of user's decryption keys that is appropriate for decrypting one
of the content-encryption keys, decrypts the content-encryption key, and
prepares the cipher for decrypting the encrypted content.
|
int |
decryptSymmetricKey(java.security.PrivateKey recipientPrivateKey,
int recipientInfoIndex)
Uses the specified private key to decrypt this S/MIME object.
|
void |
decryptSymmetricKey(User user)
Locates one of user's decryption keys that is appropriate for decrypting one
of the content-encryption keys, decrypts the content-encryption key, and
prepares the cipher for decrypting the encrypted content.
|
AlgorithmID |
getEncryptionAlgorithm()
Returns the content-encryption algorithm (including any associated
parameters) of this SMimeEncrypted object.
|
int |
getRecipientInfoIndex(java.security.cert.X509Certificate recipientCertificate)
Returns the recipient info index matching to the supplied recipient certificate.
|
ASN1Object |
toASN1Object()
Returns the S/MIME enveloped message as an ASN1Object.
|
byte[] |
toByteArray()
Returns the S/MIME enveloped message as byte array.
|
void |
writeTo(java.io.OutputStream os)
Writes this SMimeEncrypted object to the supplied output stream.
|
void |
writeTo(java.io.OutputStream os,
int blockSize)
Writes this SMimeEncrypted object to the supplied output stream.
|
addRecipientInfo, getContentType, getEncryptedContentInfo, getInputStream, getRecipientInfo, getRecipientInfos, getVersion, setBlockSize, setRecipientInfos, setupCipher, setupCipher, toASN1Object, toString, toStringpublic SMimeEncrypted(byte[] content,
AlgorithmID contentEA,
int keyLength)
throws java.security.NoSuchAlgorithmException
This constructor automatically will create the symmetric content encryption key for the specified algorithm.
content - the content of the message which shall be envelopedcontentEA - the content encryption algorithm to be used, either
RC2-CBC, DES-EDE3_CBC, or DES-CBCkeyLength - the length of the key; undefined values set the
default key length for the specified algorithm (e.g. 128 for RC2)java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic SMimeEncrypted(java.io.InputStream is,
AlgorithmID contentEA,
int keyLength)
throws java.security.NoSuchAlgorithmException
This constructor automatically will create the symmetric content encryption key for the specified algorithm.
is - an InputStream holding the data to be envelopedcontentEA - the content encryption algorithm to be used, either
RC2-CBC, DES-EDE3_CBC, or DES-CBCkeyLength - the length of the key; undefined values set the
default key length for the specified algorithm (e.g. 128 for RC2)java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic SMimeEncrypted(java.io.InputStream is)
throws java.io.IOException
Do not use this constructor for supplying the content data
to be enveloped. This constructor may be used by the recipient for parsing an
already exisiting SMimeEncrypted object, supplied as BER encoding
from an input stream, that may have been created by means of the
writeTo method.
Use the SMimeEncrypted(InputStream is, AlgorithmID contentEA, int keyLength)
constructor for supplying the content data to be enveloped when creating a
SMimeEncrypted object.
is - the input stream where the BER encoded message shall be read fromjava.io.IOException - if an I/O error occurspublic void decode(java.io.InputStream is)
throws java.io.IOException
DerInputStream,
internally a DerInputStream is created before parsing the data.decode in interface ContentStreamdecode in class EnvelopedDataStreamis - the InputStream holding a BER encoded SMimeEncrypted objectjava.io.IOException - if an I/O error occurs during reading from the InputStreampublic int getRecipientInfoIndex(java.security.cert.X509Certificate recipientCertificate)
recipientCertificate - the certificate of the recipient-1 if no recipient info belonging to the given
certificate can be foundpublic int decryptSymmetricKey(java.security.PrivateKey recipientPrivateKey,
int recipientInfoIndex)
throws SMimeException,
java.security.InvalidKeyException
recipientPrivateKey - the private of the recipientrecipientInfoIndex - specifies which RecipientInfo the private key
belongs toSMimeException - if there is an error while decrypting the datajava.security.InvalidKeyException - if the private key cannot be used for
decrypting the encrypted content encryption keypublic void decryptSymmetricKey(User user) throws UserNotLoggedInException, NotARecipientException, SMimeException
The cipher will be only initialized for decrypting with this call; The
encrypted-content decryption actually is done when the data is read by
calling the getInputStream method. So don´t call
this method before decrypting the encrypted content-encryption key!
user - the userUserNotLoggedInException - if the user is not logged inNotARecipientException - if the user is not listed as a recipient (unable to decrypt the content)SMimeException - if an error occurs while decrypting the content-encryption key or
setting up the cipher for decrypting the contentpublic void decryptSymmetricKey(KeyAndCertificateSource keyAndCertificateSource) throws NotARecipientException, SMimeException
The cipher will be only initialized for decrypting with this call; The
encrypted-content decryption actually is done when the data is read by
calling the getInputStream method. So don´t call
this method before decrypting the encrypted content-encryption key!
keyAndCertificateSource - a user's keys and certificatesNotARecipientException - if the user is not listed as a recipient (unable to decrypt the content)SMimeException - if an error occurs while decrypting the content-encryption key or
setting up the cipher for decrypting the contentpublic void addRecipient(java.security.cert.X509Certificate certificate,
AlgorithmID keyEA)
throws SMimeException,
java.security.NoSuchAlgorithmException
certificate - the certificate of the recipientkeyEA - the algorithm to use for encrypting the symmetric key
(i.e AlgorithmID.rsaEncryption)SMimeException - if it was not possible to encrypt the symmetric key for this recipientjava.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithmpublic AlgorithmID getEncryptionAlgorithm()
public byte[] toByteArray()
throws SMimeException
SMimeException - if an exception occurs when encoding this objectpublic ASN1Object toASN1Object() throws PKCSException
toASN1Object in interface ContentStreamtoASN1Object in class EnvelopedDataStreamPKCSException - if an error occurs while building the
ASN.1 objectpublic void writeTo(java.io.OutputStream os)
throws java.io.IOException
writeTo in class EnvelopedDataStreamos - the output stream to which this SMimeEncrypted shall be writtenjava.io.IOException - if an I/O error occurs while writing to the streampublic void writeTo(java.io.OutputStream os,
int blockSize)
throws java.io.IOException
blockSize parameter indicates the block size to
be used for performimg block encoding.writeTo in class EnvelopedDataStreamos - the output stream to which this SMimeEncrypted shall be writtenblockSize - the block size for using block encodingjava.io.IOException - if an I/O error occurs while writing to the stream