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!)