Guest User

Untitled

a guest
Mar 7th, 2012
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.00 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment