Save This Page
Home » crypto-143 » org.bouncycastle.mail.smime.examples » [javadoc | source]
    1   package org.bouncycastle.mail.smime.examples;
    2   
    3   import java.io.ByteArrayInputStream;
    4   import java.io.FileOutputStream;
    5   import java.io.IOException;
    6   import java.math.BigInteger;
    7   import java.security.GeneralSecurityException;
    8   import java.security.KeyPair;
    9   import java.security.KeyPairGenerator;
   10   import java.security.PrivateKey;
   11   import java.security.PublicKey;
   12   import java.security.SecureRandom;
   13   import java.security.cert.CertStore;
   14   import java.security.cert.CollectionCertStoreParameters;
   15   import java.security.cert.X509Certificate;
   16   import java.util.ArrayList;
   17   import java.util.Date;
   18   import java.util.List;
   19   import java.util.Properties;
   20   
   21   import javax.mail.Address;
   22   import javax.mail.Message;
   23   import javax.mail.Session;
   24   import javax.mail.internet.InternetAddress;
   25   import javax.mail.internet.MimeBodyPart;
   26   import javax.mail.internet.MimeMessage;
   27   import javax.mail.internet.MimeMultipart;
   28   
   29   import org.bouncycastle.asn1.ASN1EncodableVector;
   30   import org.bouncycastle.asn1.ASN1InputStream;
   31   import org.bouncycastle.asn1.ASN1Sequence;
   32   import org.bouncycastle.asn1.cms.AttributeTable;
   33   import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
   34   import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
   35   import org.bouncycastle.asn1.smime.SMIMECapability;
   36   import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
   37   import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
   38   import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
   39   import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
   40   import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
   41   import org.bouncycastle.asn1.x509.X509Extensions;
   42   import org.bouncycastle.asn1.x509.X509Name;
   43   import org.bouncycastle.x509.X509V3CertificateGenerator;
   44   import org.bouncycastle.mail.smime.SMIMESignedGenerator;
   45   
   46   /**
   47    * a simple example that creates a single signed mail message.
   48    */
   49   public class CreateSignedMail
   50   {
   51       //
   52       // certificate serial number seed.
   53       //
   54       static int  serialNo = 1;
   55   
   56       static AuthorityKeyIdentifier createAuthorityKeyId(
   57           PublicKey pub) 
   58           throws IOException
   59       {
   60           ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded());
   61           SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
   62               (ASN1Sequence)new ASN1InputStream(bIn).readObject());
   63   
   64           return new AuthorityKeyIdentifier(info);
   65       }
   66   
   67       static SubjectKeyIdentifier createSubjectKeyId(
   68           PublicKey pub) 
   69           throws IOException
   70       {
   71           ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded());
   72   
   73           SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
   74               (ASN1Sequence)new ASN1InputStream(bIn).readObject());
   75   
   76           return new SubjectKeyIdentifier(info);
   77       }
   78   
   79       /**
   80        * create a basic X509 certificate from the given keys
   81        */
   82       static X509Certificate makeCertificate(
   83           KeyPair subKP,
   84           String  subDN,
   85           KeyPair issKP,
   86           String  issDN) 
   87           throws GeneralSecurityException, IOException
   88       {
   89           X509Name   xName   = new X509Name(subDN);
   90           PublicKey  subPub  = subKP.getPublic();
   91           PrivateKey issPriv = issKP.getPrivate();
   92           PublicKey  issPub  = issKP.getPublic();
   93           
   94           X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
   95           
   96           v3CertGen.setSerialNumber(BigInteger.valueOf(serialNo++));
   97           v3CertGen.setIssuerDN(new X509Name(issDN));
   98           v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
   99           v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)));
  100           v3CertGen.setSubjectDN(new X509Name(subDN));
  101           v3CertGen.setPublicKey(subPub);
  102           v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");
  103   
  104           v3CertGen.addExtension(
  105               X509Extensions.SubjectKeyIdentifier,
  106               false,
  107               createSubjectKeyId(subPub));
  108   
  109           v3CertGen.addExtension(
  110               X509Extensions.AuthorityKeyIdentifier,
  111               false,
  112               createAuthorityKeyId(issPub));
  113   
  114           return v3CertGen.generateX509Certificate(issPriv);
  115       }
  116   
  117       public static void main(
  118           String args[])
  119           throws Exception
  120       {
  121           //
  122           // set up our certs
  123           //
  124           KeyPairGenerator    kpg  = KeyPairGenerator.getInstance("RSA", "BC");
  125   
  126           kpg.initialize(1024, new SecureRandom());
  127   
  128           //
  129           // cert that issued the signing certificate
  130           //
  131           String              signDN = "O=Bouncy Castle, C=AU";
  132           KeyPair             signKP = kpg.generateKeyPair();
  133           X509Certificate     signCert = makeCertificate(
  134                                           signKP, signDN, signKP, signDN);
  135   
  136           //
  137           // cert we sign against
  138           //
  139           String              origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
  140           KeyPair             origKP = kpg.generateKeyPair();
  141           X509Certificate     origCert = makeCertificate(
  142                                           origKP, origDN, signKP, signDN);
  143   
  144           List                certList = new ArrayList();
  145   
  146           certList.add(origCert);
  147           certList.add(signCert);
  148   
  149           //
  150           // create a CertStore containing the certificates we want carried
  151           // in the signature
  152           //
  153           CertStore           certsAndcrls = CertStore.getInstance(
  154                                   "Collection",
  155                                   new CollectionCertStoreParameters(certList), "BC");
  156   
  157           //
  158           // create some smime capabilities in case someone wants to respond
  159           //
  160           ASN1EncodableVector         signedAttrs = new ASN1EncodableVector();
  161           SMIMECapabilityVector       caps = new SMIMECapabilityVector();
  162   
  163           caps.addCapability(SMIMECapability.dES_EDE3_CBC);
  164           caps.addCapability(SMIMECapability.rC2_CBC, 128);
  165           caps.addCapability(SMIMECapability.dES_CBC);
  166   
  167           signedAttrs.add(new SMIMECapabilitiesAttribute(caps));
  168   
  169           //
  170           // add an encryption key preference for encrypted responses -
  171           // normally this would be different from the signing certificate...
  172           //
  173           IssuerAndSerialNumber   issAndSer = new IssuerAndSerialNumber(
  174                   new X509Name(signDN), origCert.getSerialNumber());
  175   
  176           signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer));
  177   
  178           //
  179           // create the generator for creating an smime/signed message
  180           //
  181           SMIMESignedGenerator gen = new SMIMESignedGenerator();
  182   
  183           //
  184           // add a signer to the generator - this specifies we are using SHA1 and
  185           // adding the smime attributes above to the signed attributes that
  186           // will be generated as part of the signature. The encryption algorithm
  187           // used is taken from the key - in this RSA with PKCS1Padding
  188           //
  189           gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null);
  190   
  191           //
  192           // add our pool of certs and cerls (if any) to go with the signature
  193           //
  194           gen.addCertificatesAndCRLs(certsAndcrls);
  195   
  196           //
  197           // create the base for our message
  198           //
  199           MimeBodyPart    msg = new MimeBodyPart();
  200   
  201           msg.setText("Hello world!");
  202   
  203           //
  204           // extract the multipart object from the SMIMESigned object.
  205           //
  206           MimeMultipart mm = gen.generate(msg, "BC");
  207   
  208           //
  209           // Get a Session object and create the mail message
  210           //
  211           Properties props = System.getProperties();
  212           Session session = Session.getDefaultInstance(props, null);
  213   
  214           Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>");
  215           Address toUser = new InternetAddress("example@bouncycastle.org");
  216   
  217           MimeMessage body = new MimeMessage(session);
  218           body.setFrom(fromUser);
  219           body.setRecipient(Message.RecipientType.TO, toUser);
  220           body.setSubject("example signed message");
  221           body.setContent(mm, mm.getContentType());
  222           body.saveChanges();
  223   
  224           body.writeTo(new FileOutputStream("signed.message"));
  225       }
  226   }

Save This Page
Home » crypto-143 » org.bouncycastle.mail.smime.examples » [javadoc | source]