How to use Javamail-Crypto with S/MIME provider :

Needs :

Lasted Api Javamail-Crypto :
http://javamail-crypto.sourceforge.net/

- javamail-crypto_060622.jar
- javamail-crypto-bouncycastle-smime_060622.jar

Install this Jars in Classpath of your application.

There are currently two providers available : one for S/MIME using the BouncyCastle provider,
and one for OpenPGP based on the Cryptix provider.

----

Lasted Api Bouncy Castle (for me Jdk1.4) :
http://www.bouncycastle.org/latest_releases.html

- bcmail-jdk14-138.jar
- bcprov-jdk14-138.jar

Install this Jars in your Classpath of your application.

----

WARNING:

If you have a exception like : java.lang.SecurityException: Unsupported keysize or algorithm parameters,
You need lasted Api Java Cryptography Extension (JCE) with Unlimited Strength Jurisdiction Policy Files (for me Jsdk1.4) :
http://java.sun.com/j2se/1.4.2/download.html (see end of page "Other Downloads")

Due to import control restrictions, the version of JCE policy files that
are bundled in the J2SDK, v 1.4.2 environment allow "strong" but
limited cryptography to be used. This download bundle provides "unlimited strength"
policy files which contain no restrictions on cryptographic strengths.

Install Jars file in jce_policy-1_4_2.zip inside the JRE (for me \j2sdk1.4.x_xx\jre\lib\security), two Jars :
- local_policy.jar
- US_export_policy.jar

----

We need to import (test validity) your certificate .p12 in your JRE :
(here certificate come from "Thawte Personal Freemail Issuing CA")

$>keytool -v -list -keystore personnal.p12 -storetype pkcs12
Enter keystore password:  *******

Keystore type: pkcs12
Keystore provider: SunJSSE

Your keystore contains 1 entry

Alias name: thawte freemail member's thawte consulting (pty) ltd. id
Creation date: 02-Jan-2008
Entry type: keyEntry
Certificate chain length: 3
Certificate[1]:
Owner: EMAILADDRESS=xxx@xxx.fr, CN=Thawte Freemail Member
Issuer: CN=Thawte Personal Freemail Issuing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
Serial number: ce845
Valid from: Sun Aug 22 11:54:25 CEST 2004 until: Mon Aug 22 11:54:25 CEST 2005
Certificate fingerprints:
         MD5:  F0:E6:03:8F:3A:E6:40:26:CE:A8:3D:EE:FB:2E:3F:4D
         SHA1: 04:B4:B4:E1:24:DE:39:14:74:D1:15:45:51:7F:DD:9F:56:05:BE:AE
Certificate[2]:
Owner: CN=Thawte Personal Freemail Issuing CA, O=Thawte Consulting (Pty) Ltd., C=ZA
Issuer: EMAILADDRESS=personal-freemail@thawte.com, CN=Thawte Personal Freemail CA, OU=Certification Services Division, O
=Thawte Consulting, L=Cape Town, ST=Western Cape, C=ZA
Serial number: d
Valid from: Thu Jul 17 02:00:00 CEST 2003 until: Wed Jul 17 01:59:59 CEST 2013
Certificate fingerprints:
         MD5:  7C:B3:90:05:05:EF:D7:BB:DC:BF:30:32:F9:5E:D3:F0
         SHA1: BC:F0:3A:B1:BD:9A:08:9B:EB:46:8D:AF:99:47:5E:83:18:39:99:0F
Certificate[3]:
Owner: EMAILADDRESS=personal-freemail@thawte.com, CN=Thawte Personal Freemail CA, OU=Certification Services Division, O=
Thawte Consulting, L=Cape Town, ST=Western Cape, C=ZA
Issuer: EMAILADDRESS=personal-freemail@thawte.com, CN=Thawte Personal Freemail CA, OU=Certification Services Division, O
=Thawte Consulting, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 0
Valid from: Mon Jan 01 01:00:00 CET 1996 until: Fri Jan 01 00:59:59 CET 2021
Certificate fingerprints:
         MD5:  1E:74:C3:86:3C:0C:35:C5:3E:C2:7F:EF:3C:AA:3C:D9
         SHA1: 20:99:00:B6:3D:95:57:28:14:0C:D1:36:22:D8:C6:87:A4:EB:00:85

----
    
Here simple example of encrypted mail with pk12 public key (see Object Pop3.java & EMail.java) :
    
[...]

import net.suberic.crypto.EncryptionKeyManager;
import net.suberic.crypto.EncryptionManager;
import net.suberic.crypto.EncryptionUtils;

[...]

/**
 * Méthode sendEncryptedMail, envoie un mail simple encrypté par une clé public.
 *
 * @param _from         Adresse de départ
 * @param _to             Adresse du destinataire
 * @param _subject         Sujet du mail
 * @param _msg             Corps du message (simple texte)
 * @param _filepk12     Objet File .p12
 * @param _smimePw         keystore password
 * @param _alias         Nom convivial du certificat (Alias name)
 *
 * @exception            Exception Si une erreur survient.
 */
public void sendEncryptedMail(String _from, String _to, String _subject, String _msg, File _filepk12, String _smimePw, String _alias)
throws Exception
{
    // Get session
    session = Session.getInstance((Properties) getSessionProperties(), null);

    // debug ?
    session.setDebug(debug);

    // Define message
    MimeMessage message = new MimeMessage(session);

    try
    {
        
        StringTokenizer b_stk = new StringTokenizer(_from, ",;");
        while (b_stk.hasMoreTokens())
        {
            message.setFrom(new InternetAddress(b_stk.nextToken()));
            break;
        }

        StringTokenizer a_stk = new StringTokenizer(_to, ",;");
        while (a_stk.hasMoreTokens())
        {
            addToAddress(a_stk.nextToken());
        }
        //message.addRecipient(Message.RecipientType.TO, new InternetAddress(_to));

        for (int i = 0; i < a_destinationTO.size(); i++)
            message.addRecipient(Message.RecipientType.TO, (Address) a_destinationTO.elementAt(i));
        for (int i = 0; i < a_destinationCC.size(); i++)
            message.addRecipient(Message.RecipientType.CC, (Address) a_destinationCC.elementAt(i));
        for (int i = 0; i < a_destinationBCC.size(); i++)
            message.addRecipient(Message.RecipientType.BCC, (Address) a_destinationBCC.elementAt(i));
        if (m_addressReply != null)
            message.setReplyTo(m_addressReply);

        message.addHeaderLine("X-Priority: " + s_priorities[m_Priority]);
        Calendar c = Calendar.getInstance(Locale.FRANCE);
        message.setSentDate(c.getTime());
        message.setSubject(_subject, charset);
        message.setText(_msg, charset);

        message.saveChanges(); // don't forget this
        
        // get the S/MIME EncryptionUtilities
        EncryptionUtils smimeUtils = EncryptionManager.getEncryptionUtils(EncryptionManager.SMIME);
          
        // load the S/MIME keystore from the given file.
        char[] smimePw = new String(_smimePw).toCharArray();
        EncryptionKeyManager smimeKeyMgr = smimeUtils.createKeyManager();
        smimeKeyMgr.loadPublicKeystore(new FileInputStream(_filepk12), smimePw);
        
        // get the S/MIME public key for encryption
        java.security.Key smimeKey = smimeKeyMgr.getPublicKey(_alias);
        
        // encrypt the message
        MimeMessage smimeEncryptedMsg = smimeUtils.encryptMessage(session, message, smimeKey);
        
        if (user != null && pass != null)
        {
            // Send message with authentification!
            Transport tr = session.getTransport("smtp");
            tr.connect(MailHost, user, pass);
            smimeEncryptedMsg.saveChanges(); // don't forget this
            tr.sendMessage(smimeEncryptedMsg, smimeEncryptedMsg.getAllRecipients());
            tr.close();
        }
        else
        {
            // Send message
            Transport.send(smimeEncryptedMsg);
        }
    }
    catch (AddressException ae)
    {
        throw new Exception("EMail.sendEncryptedMail Error : " + ae);
        //System.out.println(ae);
    }
    catch (MessagingException me)
    {
        throw new Exception("EMail.sendEncryptedMail Error : " + me);
        //System.out.println(me);
    }
}

----

Here simple example for decrypt mail with pk12 private key :

/**
* Méthode ReadEncryptedMessage, récupère un S/MIME Encrypted Message
*
* @param pop_message         Objet MimeMessage à décoder...
* @param _filepk12             Objet File .p12
* @param _smimePw             keystore password
* @param _alias                 Nom convivial du certificat (Alias name)
* @return MimeMessage        Retourne un MimeMessage décrypté
*/
public static MimeMessage ReadEncryptedMessage(MimeMessage pop_message, File _filepk12, String _smimePw, String _alias)
throws Exception
{
    String cryptotype = EncryptionManager.checkEncryptionType(pop_message);
    EncryptionUtils cryptoUtils = EncryptionManager.getEncryptionUtils(cryptotype);
    
    EncryptionKeyManager keyMgr = cryptoUtils.createKeyManager();
    char[] smimePw = new String(_smimePw).toCharArray();
        
    keyMgr.loadPrivateKeystore(new FileInputStream(_filepk12), smimePw);
    
    MimeMessage decryptedMsg = null;
      
    Key privateKey = keyMgr.getPrivateKey(_alias, smimePw);
    try
    {
        decryptedMsg = cryptoUtils.decryptMessage(null, pop_message, privateKey);
    }
    catch (Exception e)
    {
        Object o = pop_message.getContent();
        System.err.println("msg.getContent() = " + o + ", a " + o.getClass().getName());
        System.err.println("error decrypting message with key " + privateKey + ":  " + e);
        e.printStackTrace();
    }

    return decryptedMsg;
}

----

Here simple example for signed mail with pk12 private key :

/**
 * Méthode sendSignedMail, envoie un mail simple signé par une clé privée.
 *
 * @param _from         Adresse de départ
 * @param _to             Adresse du destinataire
 * @param _subject         Sujet du mail
 * @param _msg             Corps du message (simple texte)
 * @param _filepk12     Objet File .p12
 * @param _smimePw         keystore password
 * @param _alias         Nom convivial du certificat (Alias name)
 * @exception            Exception Si une erreur survient.
 */
public void sendSignedMail(String _from, String _to, String _subject, String _msg, File _filepk12, String _smimePw, String _alias)
throws Exception
{
    // Get session
    session = Session.getInstance((Properties) getSessionProperties(), null);

    // debug ?
    session.setDebug(debug);

    // Define message
    MimeMessage message = new MimeMessage(session);

    try
    {
        
        StringTokenizer b_stk = new StringTokenizer(_from, ",;");
        while (b_stk.hasMoreTokens())
        {
            message.setFrom(new InternetAddress(b_stk.nextToken()));
            break;
        }

        StringTokenizer a_stk = new StringTokenizer(_to, ",;");
        while (a_stk.hasMoreTokens())
        {
            addToAddress(a_stk.nextToken());
        }
        //message.addRecipient(Message.RecipientType.TO, new InternetAddress(_to));

        for (int i = 0; i < a_destinationTO.size(); i++)
            message.addRecipient(Message.RecipientType.TO, (Address) a_destinationTO.elementAt(i));
        for (int i = 0; i < a_destinationCC.size(); i++)
            message.addRecipient(Message.RecipientType.CC, (Address) a_destinationCC.elementAt(i));
        for (int i = 0; i < a_destinationBCC.size(); i++)
            message.addRecipient(Message.RecipientType.BCC, (Address) a_destinationBCC.elementAt(i));
        if (m_addressReply != null)
            message.setReplyTo(m_addressReply);

        message.addHeaderLine("X-Priority: " + s_priorities[m_Priority]);
        Calendar c = Calendar.getInstance(Locale.FRANCE);
        message.setSentDate(c.getTime());
        message.setSubject(_subject, charset);
        message.setText(_msg, charset);

        message.saveChanges(); // don't forget this
        
        // get the S/MIME EncryptionUtilities
        EncryptionUtils smimeUtils = EncryptionManager.getEncryptionUtils(EncryptionManager.SMIME);
          
        // load the S/MIME keystore from the given file.
        char[] smimePw = new String(_smimePw).toCharArray();
        EncryptionKeyManager smimeKeyMgr = smimeUtils.createKeyManager();
        smimeKeyMgr.loadPrivateKeystore(new FileInputStream(_filepk12), smimePw);
        
        // get our keys.
        java.security.Key smimeKey = smimeKeyMgr.getPrivateKey(_alias, smimePw);
        
        // write smime message.
        MimeMessage smimeSignedMsg = smimeUtils.signMessage(session, message, smimeKey);
       
        if (user != null && pass != null)
        {
            // Send message with authentification!
            Transport tr = session.getTransport("smtp");
            tr.connect(MailHost, user, pass);
            smimeSignedMsg.saveChanges(); // don't forget this
            tr.sendMessage(smimeSignedMsg, smimeSignedMsg.getAllRecipients());
            tr.close();
        }
        else
        {
            // Send message
            Transport.send(smimeSignedMsg);
        }
    }
    catch (AddressException ae)
    {
        throw new Exception("EMail.sendSignedMail Error : " + ae);
        //System.out.println(ae);
    }
    catch (MessagingException me)
    {
        throw new Exception("EMail.sendSignedMail Error : " + me);
        //System.out.println(me);
    }
}


----

Here simple example for check signed mail with pk12 public key :

/**
* Méthode CheckSignedMessage, check un S/MIME Signed Message
*
* @param pop_message         Objet MimeMessage a décodé...
* @param _filepk12             Objet File .p12
* @param _smimePw             keystore password
* @param _alias                 Nom convivial du certificat (Alias name)
* @return boolean            Retourne true si la signature est ok!
* @exception                    Si par exemple le certificat n'est plus valide...
*/
public static boolean CheckSignedMessage(MimeMessage pop_message, File _filepk12, String _smimePw, String _alias)
throws Exception
{
    String cryptotype = EncryptionManager.checkEncryptionType(pop_message);
    EncryptionUtils cryptoUtils = EncryptionManager.getEncryptionUtils(cryptotype);
      
    EncryptionKeyManager keyMgr = cryptoUtils.createKeyManager();
    char[] smimePw = new String(_smimePw).toCharArray();
        
    keyMgr.loadPublicKeystore(new FileInputStream(_filepk12), smimePw);
    
    // good or not ?
    boolean goodSignature = false;
    
    Key publicKey = keyMgr.getPublicKey(_alias);
    cryptoUtils.checkSignature(pop_message, publicKey);
    
    try
    {
        goodSignature = cryptoUtils.checkSignature(pop_message, publicKey);
    }
    catch (Exception e)
    {
        Object o = pop_message.getContent();
        System.err.println("msg.getContent() = " + o + ", a " + o.getClass().getName());
        System.err.println("error decrypting message with key " + publicKey + ":  " + e);
        e.printStackTrace();
    }
    
    return goodSignature;
}

          
(Mmmh... Strange world, we need to hash code for feel free!)