random technical thoughts from the Nominet technical team

Verifying PGP signed Messages Using Bouncy Castle

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Posted by chris on Jan 19th, 2006

If you need to do any Cryptography in Java then you use the
Java Cryptography Architecture
(JCA) and the Java Cryptography Extension (JCE) with a choice of implementation provider.

To validate PGP signed emails we have chosen to use the popular JCA and JCE provider from
The Legion of the Bouncy Castle. The Bouncy Castle software is free to use and is distributed under a license based on the MIT X Consortium license. The provider’s role is to provide the actual implementation for the API.

Bouncy Castle is a complete Crypto API for Java but unfortunately the lack of documentation and code examples don’t make it easy to use.

Installing The Provider

There are two ways to install the Bouncy Castle provider, you can either configure the JRE to preload the provider or do it dynamically at runtime.

To configure your JRE then edit the following file

jre/lib/security/java.security

and add the following line

security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

where N is the next available number.

To simplify deployment we tend to install the provider at runtime by adding the following line to a class constructor.


Security.addProvider(new BouncyCastleProvider());

Verifying Messages
Nominet receives messages from its tag holders which have been signed using their private key,
to verify a signed message we use the tag holders public key. The signed messages can be verified with Bouncy Castle using the following code example.

public  boolean
verifyFile(InputStream fileStreamIn, PGPPublicKey keyIn)
throws Exception
{
boolean verify = false;
ArmoredInputStream    aIn = new ArmoredInputStream(fileStreamIn, true);

//
// read the input, making sure we ingore the last newline.
//
int                   ch;
boolean               newLine = false;
ByteArrayOutputStream bOut = new ByteArrayOutputStream();

while ((ch = aIn.read()) >= 0 && aIn.isClearText())
{
if (newLine)
{
bOut.write((byte)'n');
newLine = false;
}
if (ch == 'n')
{
newLine = true;
continue;
}

bOut.write((byte)ch);
}

PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);

Object o = pgpFact.nextObject();
if (o instanceof PGPSignatureList) {
PGPSignatureList list = (PGPSignatureList)o;
if (list.size() > 0) {
PGPSignature sig = list.get(0);
sig.initVerify(keyIn, "BC");
sig.update(bOut.toByteArray());
verify = sig.verify();
}

}

return verify;
}

The problems occur when Mail Transport Agents (MTA’s) add spurious white space to the email body after the message has been signed, this causes the message to fail the verification process since the message digests no longer match.

One solution is to strip the extra whitespace from the message using regular expressions, we have found the following Java regex’s work quite well for a large range of emails.

message = orgMessage.replaceAll(" *n", "n");
message = orgMessage.replaceAll(" *$", "");

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Recent Posts

Highest Rated

Categories

Archives

Meta: