Short introduction to PGPMime for Java

Maximilian Schwerin

February 2004

Copyright © 2003 Maximilian Schwerin. This software is published under the GNU LESSER GENERAL PUBLIC LICENSE, a copy of which has been included in the LGPL file shipped with the distribution of the software.

Abstract

This document describes the basic features of the PGPMime for Java API. PGPMime for Java is an open source project. It allows the user to secure internet mails using PGP.

Introduction

The fact that many people today use internet mail as method to comunicate makes it more and more important to create means to secure this way of message transfer.

PGP to encrypt and sign any message and PGPMime for securing internet mail have been around for some time now. There has however not been an API available to use this functionality together with the JavaMail API provided by SUN for internet mail handling.

This is where PGPMime for Java steps in. It is an API extending the standard classes of the JavaMail package to allow the user to encrypt, decrypt, sign and verify internet mails using Java.

It does however not provide the encryption functionality of itself. It needs to use cryptography providers like a native program (GNU Privacy Guard, PGP), a native library, or another Java library (Cryptix OpenPGP Provider) to do the encryption and signing. PGPMime for Java serves as a middleware layer between the cryptography provider and JavaMail.

Installation

The distribution of PGPMime for Java includes the JAR Archive file 'jpgpmime.jar'. Also included in the distribution are the files 'activation.jar', 'mail.jar' and 'log4j.jar'. PGPMime for Java depends on these libraries. Include these four files into your CLASSPATH and you are set to run.

Creating internet mails using PGPMime for Java

Conforming to RFC 1847 an internet mail containing ecrypted or signed data has a multipart/signed or a multipart/encrypted as main content.

PGPMime for Java contains two subclasses of the javax.mail.internet.MimeMultipart class provided by SUN's JavaMail API. MimeMultipartSigned handles signed data and MimeMultipartEncrypted handles encrypted data.

As the API should be extendable the implementation of the PGP functionality is not directly included in these classes. Four interfaces (BodyPartEncrypter, BodyPartDecrypter, BodyPartSigner, BodyPartVerifier) need to be implemented to create wrappers around already existing PGP implementations or to provide the necessary functionality directely.

As of release 0.1 PGPMime for Java implements wrapper classes for the command line program GnuPG. The wrapper to encrypt and decrypt data is created as follows:

String[] recipients = new String[]{"trial.user@sourceforge.net"};
BodyPartEncrypter encrypter = new GnuPGBodyPartEncrypter("/usr/bin/gpg",
                                                         recipients);

The creation of the wrapper to sign and verify data using GnuPG is very similar:

BodyPartSigner signer
= new GnuPGBodyPartSigner("/usr/bin/gpg",
                          authenticator);

In both cases the string "/usr/bin/gpg" is the path to the GnuPG commandline executable. This path will vary depending on the system used.

The authenticator is an implementation of the interface PGPAuthenticator that provides passphrases for decrypting and signing purposes.

These wrapper classes are used to create the MimeMultipartSigned and MimeMultipartEncrypted objects.

/* create a multipart/signed */
MimeBodyPart mbp1 = new MimeBodyPart();
mbp.setText("This is the text to be signed.");

MimeMultipartSigned mms
= MimeMultipartSigned.createInstance(mbp, signer);

/* create a mimemessage using the multipart/signed */
MimeMessage mm = new MimeMessage(session);
mm.setContent(mms);

/* ************************************************************************** */

/* create a multipart/encrypted */
MimeBodyPart mbp1 = new MimeBodyPart();
mbp.setText("This is the text to be encrypted.");

MimeMultipartEncrypted mme
= MimeMultipartEncrypted.createInstance(mbp, encrypter);

/* create a mimemessage using the multipart/encrypted */
MimeMessage mm = new MimeMessage(session);
mm.setContent(mme);

The createInstance methods are not restricted to the BodyPart object. Multipart objects can also be used as content.

Handling existing messages

Installing PGPMime for Java correctly registers classes for handling PGPMime content in JavaMail. This means that every time a message is parsed into a javax.mail.internet.MimeMessage object the parser will create instances of the classes MimeMultipartEncrypted and MimeMultipartSigned if he finds them in the message source.

If a MimeMessage contains encrypted content and the user wants to access the cleartext it is necessary to find the MimeMultipartEncrypted in the message and then decrypt it using an implementation of the BodyPartDecrypter:

BodyPartDecrypter decrypter
= new GnuPGBodyPartEncrypter("/usr/bin/gpg",
                             authenticator);

if (mimeMessage.getContent() instanceof MimeMultipartEncrypted) {
    BodyPart decryptedBP = ((MimeMultipartEncrypted)mimeMessage.getContent()).decrypt(decrypter);    
}

If a MimeMessage contains signed content and the user wants to verify the signature it is necessary to find the MimeMultipartSigned in the message and then verify the signature using an implementation of the BodyPartVerifier:

BodyPartVerifier verifier
= new GnuPGBodyPartSigner("/usr/bin/gpg",
                          authenticator);

if (mimeMessage.getContent() instanceof MimeMultipartSigned) {
    ((MimeMultipartSigned)mimeMessage).getContent().decrypt(decrypter);
}

The method used to verify the signature throws an Exception if the verification fails.

Conclusions

Hopefully this document is a help to those who wish to use this library. Most of the code used in this document are also included in the jUnit tests. It may help to look at the tests to get a better understanding for the functionality of the library. If there are any suggestions concerning this document or the library itself please feel free to contact the author via the Sourceforge Project Page.