Friday, October 19, 2012

PGP and SOA

My environment:
      SOA 11.1.1.6
      Java 1.6.x
Goal:
      sftp adapter to grab a PGP encrypted file, then decrypt the file in the SOA composite then process the data. You will be supplied with a PGP private key file (binary key ring, or ascii key), and pass phrase to decode the file.

My solution:
     use java embedding to decrypt PGP file. In essence, it's a Java solution.

Java part:

Here is how to do it in Java:
1. go to Bounce Castle to download the latest jars


Download
 bcpg-jdk15on-147.jar 
bcprov-jdk15on-147.jar 

2. online resource to use the package to encrypt/decrypt:


3. I added a simple main() to the above PGPFileProcessor class:

public static void main(String args[]) throws Exception
{
   PGPFileProcessor pgp = new PGPFileProcessor();

   //pgp.setAsciiArmored(true); // if you want dump ascii file
   // hard code for my test
   pgp.setInputFileName("c:/pgp/java/sample_file.txt");
   pgp.setOutputFileName("c:/pgp/java/sample_file.txt.pgp");
   pgp.setPublicKeyFileName("c:/pgp/java/mypgp-pub.key"); //can be either binary or text key
   pgp.encrypt();

// decrypt the same file
   pgp.setInputFileName("c:/pgp/java/sample_file.txt.pgp");
   pgp.setOutputFileName("c:/pgp/java/sample_file-decrypted.txt");
   pgp.setSecretKeyFileName("c:/pgp/java/mypgp-pri.key"); // can be either binary or text key
   pgp.setPassphrase("mypassword");
   pgp.decrypt();
}

3. set your class path to include the jars in step 1, and compile java files from step 2

4. if you get java exceptions like:
PGPKeyRingTest: exception: java.security.InvalidKeyException: Illegal key size

You may need to download

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6


save the jars to “C:\java\jdk1.6.0_31\jre\lib\security”. Backup local_policy.jar, and US_export_policy.jar first!


5. package the compiled classes into a jar, let's call it mypgp.jar

Add Java to the composite:

1. copy  bcpg-jdk15on-147.jar, bcprov-jdk15on-147.jar and mypgp.jar (you just generated) to two locations (you need to figure out your own soa environment)
C:\Oracle\Middleware\Oracle_SOA1\soa\modules\oracle.soa.ext_11.1.1
and
C:\Oracle\Middleware\user_projects\domains\soa_domain\lib


For the first copied location, there is build.xml in that directory already, you need to run "ant" command in that directory. If you don't want to run "ant" command, you can also unjar your files into the "classes:" sub directory.
After you finish that, you need to bounce the entire SOA suite (including weblogic server).

2. code embedded java:
            <![CDATA[System.out.println("**********new pgp");      
pgp.test.com.PGPFileProcessor pgp = new pgp.test.com.PGPFileProcessor();      
      
System.out.println("*end *********new pgp");      
     
XMLElement srcElem = (XMLElement) getVariableData("inputVariable", "payload", "/client:myReqeust/client:srcFile");    
String srcFile = srcElem.getTextContent();    
String tgtFile = srcFile.substring(0, srcFile.lastIndexOf(".pgp"));    
      
args[0] = ;      
args[1] = ;      
      
      
pgp.setInputFileName(new String("/soaIntegration/pgp/receive/") + srcFile);      
pgp.setOutputFileName(new String("/soaIntegration/pgp/process/") + tgtFile);      
pgp.setSecretKeyFileName("/soaIntegration/pgp/pri-key.key");      
pgp.setPassphrase("mypassword");      
      
try {      
pgp.decrypt();      
}      
catch(Exception e)      
{      
  System.out.println("###PGP decryption failed:"+e.getMessage());      
}]]>

Additional: generate your own key pairs for test or for fun

What if you want to generate your own key pairs for test?  Here is what I did:
download "bcpg-jdk15on-147.zip" with source, then find this file PGPKeyRingTest.java in package org.bouncycastle.openpgp.test.

I modify generatetest() like below:
    public void generateTest()         throws Exception
    {
System.out.println("********* intercepted ********");
        char[]              passPhrase = "hello".toCharArray();
        KeyPairGenerator    dsaKpg = KeyPairGenerator.getInstance("DSA", "BC");
        dsaKpg.initialize(512);
...
PGPPublicKeyRing        pubRing = keyRingGen.generatePublicKeyRing();
        PGPPublicKey            vKey = null;
        PGPPublicKey            sKey = null;

  byte[] b = null;
            ByteArrayOutputStream baos = null;
            ArmoredOutputStream aos = null;
            try {
                    baos = new ByteArrayOutputStream();
                    aos = new ArmoredOutputStream(baos);
                    // get public key
                    pubRing.encode(aos);
                    aos.flush();
                    baos.flush();
                    aos.close() ;
                    b = baos.toByteArray();
                    System.out.println(new String(b));

                    baos = new ByteArrayOutputStream();
                    aos = new ArmoredOutputStream(baos);
                    // get private key
                    keyRing.encode(aos);
                    aos.flush();
                    baos.flush();
                    aos.close() ;
                    b = baos.toByteArray();
                    System.out.println(new String(b));

            } catch (Exception e) {
                    System.out.println("Exception caught while exporting SecretKeyRing"+ e);
            } finally {
                    aos.close();
                    baos.close();
            }
of course, i modified performTest() only to run generatetest().

you need to add bctest-jdk15on-147.jar to the classpath to run the above class. 

If you get java exceptions compiling or running, check step 4 above in the Java section.

There you go, you'll get your own public and private keys to play with (remember your password is "hello" in the above code, you can change it if you like).

PGP Command Line

BTW, if you happen to have the PGP command line from old PGP Corporation (currently owned by Symatec), you can generate your own keys, and test encryption and decryption from the command line.

To generate key:
   pgp --gen-key "foo@bar.com" --key-type rsa --bits 2048 --passphrase car

export the key:
     pgp --export-key-pair foo

To test encryption/decryption:
  pgp -e test.txt --recipient foo (or pgp -e test.txt --recipient foo --armor)

  pgp --decrypt test.txt.pgp  --passphrase "car"--output foo.txt

if you wonder where pgp command line stores key ring files, they are under here on windows: C:\Documents and Settings\yourUserName\My Documents\PGP. I was using the binary key rings initially before I figured out the export commands.

That's all

I assumed anyone reading this post has the basic idea how PGP works. What I demonstrated is how to use Java to decrypt a PGP file, and add the java solution to SOA composite. 





3 comments:

  1. I loved all of these posts. A lot of these things we have, but I got some really great ideas.

    pgp download

    ReplyDelete
  2. Thanks for the post, it works for me.

    ReplyDelete
  3. Does PGP encryption works on Opaque data ?

    ReplyDelete