001: package org.bouncycastle.openpgp.examples;
002:
003: import java.io.*;
004: import java.util.*;
005: import java.security.NoSuchProviderException;
006: import java.security.SecureRandom;
007: import java.security.Security;
008:
009: import org.bouncycastle.bcpg.ArmoredOutputStream;
010: import org.bouncycastle.jce.provider.BouncyCastleProvider;
011: import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
012: import org.bouncycastle.openpgp.PGPEncryptedDataList;
013: import org.bouncycastle.openpgp.PGPException;
014: import org.bouncycastle.openpgp.PGPLiteralData;
015: import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
016: import org.bouncycastle.openpgp.PGPCompressedData;
017: import org.bouncycastle.openpgp.PGPObjectFactory;
018: import org.bouncycastle.openpgp.PGPPBEEncryptedData;
019: import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
020: import org.bouncycastle.openpgp.PGPUtil;
021:
022: /**
023: * Simple routine to encrypt and decrypt using a passphrase.
024: * This service routine provides the basic PGP services between
025: * byte arrays.
026: *
027: * Note: this code plays no attention to -CONSOLE in the file name
028: * the specification of "_CONSOLE" in the filename.
029: * It also expects that a single pass phrase will have been used.
030: *
031: */
032: public class ByteArrayHandler {
033: /**
034: * decrypt the passed in message stream
035: *
036: * @param encrypted The message to be decrypted.
037: * @param passPhrase Pass phrase (key)
038: *
039: * @return Clear text as a byte array. I18N considerations are
040: * not handled by this routine
041: * @exception IOException
042: * @exception PGPException
043: * @exception NoSuchProviderException
044: */
045: public static byte[] decrypt(byte[] encrypted, char[] passPhrase)
046: throws IOException, PGPException, NoSuchProviderException {
047: InputStream in = new ByteArrayInputStream(encrypted);
048:
049: in = PGPUtil.getDecoderStream(in);
050:
051: PGPObjectFactory pgpF = new PGPObjectFactory(in);
052: PGPEncryptedDataList enc = null;
053: Object o = pgpF.nextObject();
054:
055: //
056: // the first object might be a PGP marker packet.
057: //
058: if (o instanceof PGPEncryptedDataList) {
059: enc = (PGPEncryptedDataList) o;
060: } else {
061: enc = (PGPEncryptedDataList) pgpF.nextObject();
062: }
063:
064: PGPPBEEncryptedData pbe = (PGPPBEEncryptedData) enc.get(0);
065:
066: InputStream clear = pbe.getDataStream(passPhrase, "BC");
067:
068: PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
069:
070: PGPCompressedData cData = (PGPCompressedData) pgpFact
071: .nextObject();
072:
073: pgpFact = new PGPObjectFactory(cData.getDataStream());
074:
075: PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
076:
077: InputStream unc = ld.getInputStream();
078:
079: ByteArrayOutputStream out = new ByteArrayOutputStream();
080: int ch;
081:
082: while ((ch = unc.read()) >= 0) {
083: out.write(ch);
084:
085: }
086:
087: byte[] returnBytes = out.toByteArray();
088: out.close();
089: return returnBytes;
090: }
091:
092: /**
093: * Simple PGP encryptor between byte[].
094: *
095: * @param clearData The test to be encrypted
096: * @param passPhrase The pass phrase (key). This method assumes that the
097: * key is a simple pass phrase, and does not yet support
098: * RSA or more sophisiticated keying.
099: * @param fileName File name. This is used in the Literal Data Packet (tag 11)
100: * which is really inly important if the data is to be
101: * related to a file to be recovered later. Because this
102: * routine does not know the source of the information, the
103: * caller can set something here for file name use that
104: * will be carried. If this routine is being used to
105: * encrypt SOAP MIME bodies, for example, use the file name from the
106: * MIME type, if applicable. Or anything else appropriate.
107: *
108: * @param armor
109: *
110: * @return encrypted data.
111: * @exception IOException
112: * @exception PGPException
113: * @exception NoSuchProviderException
114: */
115: public static byte[] encrypt(byte[] clearData, char[] passPhrase,
116: String fileName, int algorithm, boolean armor)
117: throws IOException, PGPException, NoSuchProviderException {
118: if (fileName == null) {
119: fileName = PGPLiteralData.CONSOLE;
120: }
121:
122: ByteArrayOutputStream encOut = new ByteArrayOutputStream();
123:
124: OutputStream out = encOut;
125: if (armor) {
126: out = new ArmoredOutputStream(out);
127: }
128:
129: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
130:
131: PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
132: PGPCompressedDataGenerator.ZIP);
133: OutputStream cos = comData.open(bOut); // open it with the final destination
134: PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
135:
136: // we want to generate compressed data. This might be a user option later,
137: // in which case we would pass in bOut.
138: OutputStream pOut = lData.open(cos, // the compressed output stream
139: PGPLiteralData.BINARY, fileName, // "filename" to store
140: clearData.length, // length of clear data
141: new Date() // current time
142: );
143: pOut.write(clearData);
144:
145: lData.close();
146: comData.close();
147:
148: PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(
149: algorithm, new SecureRandom(), "BC");
150:
151: cPk.addMethod(passPhrase);
152:
153: byte[] bytes = bOut.toByteArray();
154:
155: OutputStream cOut = cPk.open(out, bytes.length);
156:
157: cOut.write(bytes); // obtain the actual bytes from the compressed stream
158:
159: cOut.close();
160:
161: return encOut.toByteArray();
162: }
163:
164: public static void main(String[] args) throws Exception {
165: Security.addProvider(new BouncyCastleProvider());
166:
167: String passPhrase = "Dick Beck";
168: char[] passArray = passPhrase.toCharArray();
169:
170: byte[] original = "Hello world".getBytes();
171: System.out.println("Starting PGP test");
172: byte[] encrypted = encrypt(original, passArray, "iway",
173: PGPEncryptedDataGenerator.CAST5, true);
174:
175: System.out.println("\nencrypted data = '"
176: + new String(encrypted) + "'");
177: byte[] decrypted = decrypt(encrypted, passArray);
178:
179: System.out.println("\ndecrypted data = '"
180: + new String(decrypted) + "'");
181:
182: encrypted = encrypt(original, passArray, "iway",
183: PGPEncryptedDataGenerator.AES_256, false);
184:
185: System.out.println("\nencrypted data = '"
186: + new String(org.bouncycastle.util.encoders.Hex
187: .encode(encrypted)) + "'");
188: decrypted = decrypt(encrypted, passArray);
189:
190: System.out.println("\ndecrypted data = '"
191: + new String(decrypted) + "'");
192: }
193: }
|