Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 7th, 2012  |  syntax: None  |  size: 10.00 KB  |  views: 32  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. package com.common.security.pgp;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.File;
  6. import java.io.FileInputStream;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.OutputStream;
  11. import java.security.NoSuchProviderException;
  12. import java.security.SecureRandom;
  13. import java.security.Security;
  14. import java.util.Date;
  15. import java.util.Iterator;
  16.  
  17. import org.bouncycastle.bcpg.ArmoredOutputStream;
  18. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  19. import org.bouncycastle.openpgp.PGPCompressedData;
  20. import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
  21. import org.bouncycastle.openpgp.PGPEncryptedData;
  22. import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
  23. import org.bouncycastle.openpgp.PGPEncryptedDataList;
  24. import org.bouncycastle.openpgp.PGPException;
  25. import org.bouncycastle.openpgp.PGPLiteralData;
  26. import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
  27. import org.bouncycastle.openpgp.PGPObjectFactory;
  28. import org.bouncycastle.openpgp.PGPPrivateKey;
  29. import org.bouncycastle.openpgp.PGPPublicKey;
  30. import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
  31. import org.bouncycastle.openpgp.PGPPublicKeyRing;
  32. import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
  33. import org.bouncycastle.openpgp.PGPSecretKey;
  34. import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
  35. import org.bouncycastle.openpgp.PGPUtil;
  36.  
  37. /**
  38.  * Simple routine to encrypt and decrypt using a Public and Private key with passphrase. This service
  39.  * routine provides the basic PGP services between byte arrays.
  40.  *
  41.  */
  42. public class PgpEncryption {
  43.  
  44.  
  45.     private static PGPPrivateKey findSecretKey(
  46.             PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
  47.             throws PGPException, NoSuchProviderException {
  48.         PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
  49.  
  50.         if (pgpSecKey == null) {
  51.             return null;
  52.         }
  53.  
  54.         return pgpSecKey.extractPrivateKey(pass, "BC");
  55.     }
  56.  
  57.     /**
  58.      * decrypt the passed in message stream
  59.      *
  60.      * @param encrypted
  61.      *            The message to be decrypted.
  62.      * @param passPhrase
  63.      *            Pass phrase (key)
  64.      *
  65.      * @return Clear text as a byte array. I18N considerations are not handled
  66.      *         by this routine
  67.      * @exception IOException
  68.      * @exception PGPException
  69.      * @exception NoSuchProviderException
  70.      */
  71.     public static byte[] decrypt(byte[] encrypted, InputStream keyIn, char[] password)
  72.             throws IOException, PGPException, NoSuchProviderException {
  73.         InputStream in = new ByteArrayInputStream(encrypted);
  74.  
  75.         in = PGPUtil.getDecoderStream(in);
  76.  
  77.         PGPObjectFactory pgpF = new PGPObjectFactory(in);
  78.         PGPEncryptedDataList enc = null;
  79.         Object o = pgpF.nextObject();
  80.  
  81.         //
  82.         // the first object might be a PGP marker packet.
  83.         //
  84.         if (o instanceof PGPEncryptedDataList) {
  85.             enc = (PGPEncryptedDataList) o;
  86.         } else {
  87.             enc = (PGPEncryptedDataList) pgpF.nextObject();
  88.         }
  89.  
  90.  
  91.  
  92.         //
  93.         // find the secret key
  94.         //
  95.         Iterator it = enc.getEncryptedDataObjects();
  96.         PGPPrivateKey sKey = null;
  97.         PGPPublicKeyEncryptedData pbe = null;
  98.         PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
  99.                 PGPUtil.getDecoderStream(keyIn));
  100.  
  101.         while (sKey == null && it.hasNext()) {
  102.             pbe = (PGPPublicKeyEncryptedData) it.next();
  103.  
  104.             sKey = findSecretKey(pgpSec, pbe.getKeyID(), password);
  105.         }
  106.  
  107.         if (sKey == null) {
  108.             throw new IllegalArgumentException(
  109.                     "secret key for message not found.");
  110.         }
  111.  
  112.         InputStream clear = pbe.getDataStream(sKey, "BC");
  113.  
  114.  
  115.  
  116.         PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
  117.  
  118.         PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject();
  119.  
  120.         pgpFact = new PGPObjectFactory(cData.getDataStream());
  121.  
  122.         PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
  123.  
  124.         InputStream unc = ld.getInputStream();
  125.  
  126.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  127.         int ch;
  128.  
  129.         while ((ch = unc.read()) >= 0) {
  130.             out.write(ch);
  131.  
  132.         }
  133.  
  134.         byte[] returnBytes = out.toByteArray();
  135.         out.close();
  136.         return returnBytes;
  137.     }
  138.  
  139.     /**
  140.      * Simple PGP encryptor between byte[].
  141.      *
  142.      * @param clearData
  143.      *            The test to be encrypted
  144.      * @param passPhrase
  145.      *            The pass phrase (key). This method assumes that the key is a
  146.      *            simple pass phrase, and does not yet support RSA or more
  147.      *            sophisiticated keying.
  148.      * @param fileName
  149.      *            File name. This is used in the Literal Data Packet (tag 11)
  150.      *            which is really inly important if the data is to be related to
  151.      *            a file to be recovered later. Because this routine does not
  152.      *            know the source of the information, the caller can set
  153.      *            something here for file name use that will be carried. If this
  154.      *            routine is being used to encrypt SOAP MIME bodies, for
  155.      *            example, use the file name from the MIME type, if applicable.
  156.      *            Or anything else appropriate.
  157.      *
  158.      * @param armor
  159.      *
  160.      * @return encrypted data.
  161.      * @exception IOException
  162.      * @exception PGPException
  163.      * @exception NoSuchProviderException
  164.      */
  165.     public static byte[] encrypt(byte[] clearData, PGPPublicKey encKey,
  166.             String fileName,boolean withIntegrityCheck, boolean armor)
  167.             throws IOException, PGPException, NoSuchProviderException {
  168.         if (fileName == null) {
  169.             fileName = PGPLiteralData.CONSOLE;
  170.         }
  171.  
  172.         ByteArrayOutputStream encOut = new ByteArrayOutputStream();
  173.  
  174.         OutputStream out = encOut;
  175.         if (armor) {
  176.             out = new ArmoredOutputStream(out);
  177.         }
  178.  
  179.         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
  180.  
  181.         PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
  182.                 PGPCompressedDataGenerator.ZIP);
  183.         OutputStream cos = comData.open(bOut); // open it with the final
  184.         // destination
  185.         PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
  186.  
  187.         // we want to generate compressed data. This might be a user option
  188.         // later,
  189.         // in which case we would pass in bOut.
  190.         OutputStream pOut = lData.open(cos, // the compressed output stream
  191.                 PGPLiteralData.BINARY, fileName, // "filename" to store
  192.                 clearData.length, // length of clear data
  193.                 new Date() // current time
  194.                 );
  195.         pOut.write(clearData);
  196.  
  197.         lData.close();
  198.         comData.close();
  199.  
  200.         PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(
  201.                 PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(),
  202.                 "BC");
  203.  
  204.         cPk.addMethod(encKey);
  205.  
  206.         byte[] bytes = bOut.toByteArray();
  207.  
  208.         OutputStream cOut = cPk.open(out, bytes.length);
  209.  
  210.         cOut.write(bytes); // obtain the actual bytes from the compressed stream
  211.  
  212.         cOut.close();
  213.  
  214.         out.close();
  215.  
  216.         return encOut.toByteArray();
  217.     }
  218.  
  219.     private static PGPPublicKey readPublicKey(InputStream in)
  220.             throws IOException, PGPException {
  221.         in = PGPUtil.getDecoderStream(in);
  222.  
  223.         PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in);
  224.  
  225.         //
  226.         // we just loop through the collection till we find a key suitable for
  227.         // encryption, in the real
  228.         // world you would probably want to be a bit smarter about this.
  229.         //
  230.  
  231.         //
  232.         // iterate through the key rings.
  233.         //
  234.         Iterator rIt = pgpPub.getKeyRings();
  235.  
  236.         while (rIt.hasNext()) {
  237.             PGPPublicKeyRing kRing = (PGPPublicKeyRing) rIt.next();
  238.             Iterator kIt = kRing.getPublicKeys();
  239.  
  240.             while (kIt.hasNext()) {
  241.                 PGPPublicKey k = (PGPPublicKey) kIt.next();
  242.  
  243.                 if (k.isEncryptionKey()) {
  244.                     return k;
  245.                 }
  246.             }
  247.         }
  248.  
  249.         throw new IllegalArgumentException(
  250.                 "Can't find encryption key in key ring.");
  251.     }
  252.  
  253.     public static byte[] getBytesFromFile(File file) throws IOException {
  254.         InputStream is = new FileInputStream(file);
  255.  
  256.         // Get the size of the file
  257.         long length = file.length();
  258.  
  259.         if (length > Integer.MAX_VALUE) {
  260.             // File is too large
  261.         }
  262.  
  263.         // Create the byte array to hold the data
  264.         byte[] bytes = new byte[(int)length];
  265.  
  266.         // Read in the bytes
  267.         int offset = 0;
  268.         int numRead = 0;
  269.         while (offset < bytes.length
  270.                && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
  271.             offset += numRead;
  272.         }
  273.  
  274.         // Ensure all the bytes have been read in
  275.         if (offset < bytes.length) {
  276.             throw new IOException("Could not completely read file "+file.getName());
  277.         }
  278.  
  279.         // Close the input stream and return bytes
  280.         is.close();
  281.         return bytes;
  282.     }
  283.  
  284.     public static void main(String[] args) throws Exception {
  285.         Security.addProvider(new BouncyCastleProvider());
  286.  
  287.  
  288.         byte[] original = "Hello world".getBytes();
  289.         System.out.println("Starting PGP test");
  290.  
  291.         FileInputStream pubKey = new FileInputStream("/Users/me/pub.key");
  292.         byte[] encrypted = encrypt(original, readPublicKey(pubKey), null,
  293.                 true, true);
  294.  
  295.         FileOutputStream dfis = new FileOutputStream("/Users/me/enc.asc");
  296.         dfis.write(encrypted);
  297.         dfis.close();
  298.  
  299.         byte[] encFromFile = getBytesFromFile(new File("/Users/me/enc.asc"));
  300.         FileInputStream secKey = new FileInputStream("/Users/me/sec.key");
  301.  
  302.         System.out.println("\nencrypted data = '" + new String(encrypted) + "'");
  303.  
  304.         byte[] decrypted = decrypt(encFromFile, secKey, "passphrase".toCharArray());
  305.  
  306.         System.out.println("\ndecrypted data = '" + new String(decrypted) + "'");
  307.  
  308.  
  309.     }
  310. }
clone this paste RAW Paste Data