
org.bouncycastle.mail.smime.examples.SendSignedAndEncryptedMail Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcjmail-jdk15to18 Show documentation
Show all versions of bcjmail-jdk15to18 Show documentation
The Bouncy Castle Java S/MIME APIs for handling S/MIME protocols. This jar contains S/MIME APIs for JDK 1.5 to JDK 1.8. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs. The Jakarta Mail API and the Jakarta activation framework will also be needed.
The newest version!
package org.bouncycastle.mail.smime.examples;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import jakarta.activation.CommandMap;
import jakarta.activation.MailcapCommandMap;
import jakarta.mail.Message;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeMultipart;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
import org.bouncycastle.asn1.smime.SMIMECapability;
import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
import org.bouncycastle.mail.smime.SMIMEException;
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.Strings;
/**
* Example that sends a signed and encrypted mail message.
*/
public class SendSignedAndEncryptedMail
{
public static void main(String args[])
{
if (args.length != 5)
{
System.err
.println("usage: SendSignedAndEncryptedMail ");
System.exit(0);
}
try
{
MailcapCommandMap mailcap = (MailcapCommandMap)CommandMap
.getDefaultCommandMap();
mailcap
.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
mailcap
.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
mailcap
.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
mailcap
.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
mailcap
.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
CommandMap.setDefaultCommandMap(mailcap);
/* Add BC */
Security.addProvider(new BouncyCastleProvider());
/* Open the keystore */
KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
keystore.load(new FileInputStream(args[0]), args[1].toCharArray());
Certificate[] chain = keystore.getCertificateChain(args[2]);
/* Get the private key to sign the message with */
PrivateKey privateKey = (PrivateKey)keystore.getKey(args[2],
args[1].toCharArray());
if (privateKey == null)
{
throw new Exception("cannot find private key for alias: "
+ args[2]);
}
/* Create the message to sign and encrypt */
Properties props = System.getProperties();
props.put("mail.smtp.host", args[3]);
Session session = Session.getDefaultInstance(props, null);
MimeMessage body = new MimeMessage(session);
body.setFrom(new InternetAddress(args[4]));
body.setRecipient(Message.RecipientType.TO, new InternetAddress(
args[4]));
body.setSubject("example encrypted message");
body.setContent("example encrypted message", "text/plain");
body.saveChanges();
/* Create the SMIMESignedGenerator */
SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
capabilities.addCapability(SMIMECapability.dES_CBC);
ASN1EncodableVector attributes = new ASN1EncodableVector();
attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
new IssuerAndSerialNumber(
new X500Name(((X509Certificate)chain[0])
.getIssuerDN().getName()),
((X509Certificate)chain[0]).getSerialNumber())));
attributes.add(new SMIMECapabilitiesAttribute(capabilities));
SMIMESignedGenerator signer = new SMIMESignedGenerator();
signer.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(attributes)).build("DSA".equals(privateKey.getAlgorithm()) ? "SHA1withDSA" : "MD5withRSA", privateKey, (X509Certificate)chain[0]));
/* Add the list of certs to the generator */
List certList = new ArrayList();
certList.add(chain[0]);
Store certs = new JcaCertStore(certList);
signer.addCertificates(certs);
/* Sign the message */
MimeMultipart mm = signer.generate(body);
MimeMessage signedMessage = new MimeMessage(session);
/* Set all original MIME headers in the signed message */
Enumeration headers = body.getAllHeaderLines();
while (headers.hasMoreElements())
{
signedMessage.addHeaderLine((String)headers.nextElement());
}
/* Set the content of the signed message */
signedMessage.setContent(mm);
signedMessage.saveChanges();
/* Create the encrypter */
SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator();
encrypter.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator((X509Certificate)chain[0]).setProvider("BC"));
/* Encrypt the message */
MimeBodyPart encryptedPart = encrypter.generate(signedMessage,
new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build());
/*
* Create a new MimeMessage that contains the encrypted and signed
* content
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
encryptedPart.writeTo(out);
MimeMessage encryptedMessage = new MimeMessage(session,
new ByteArrayInputStream(out.toByteArray()));
/* Set all original MIME headers in the encrypted message */
headers = body.getAllHeaderLines();
while (headers.hasMoreElements())
{
String headerLine = (String)headers.nextElement();
/*
* Make sure not to override any content-* headers from the
* original message
*/
if (!Strings.toLowerCase(headerLine).startsWith("content-"))
{
encryptedMessage.addHeaderLine(headerLine);
}
}
Transport.send(encryptedMessage);
}
catch (SMIMEException ex)
{
ex.getUnderlyingException().printStackTrace(System.err);
ex.printStackTrace(System.err);
}
catch (Exception ex)
{
ex.printStackTrace(System.err);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy