001: package org.bouncycastle.openpgp.examples;
002:
003: import org.bouncycastle.bcpg.ArmoredOutputStream;
004: import org.bouncycastle.jce.provider.BouncyCastleProvider;
005: import org.bouncycastle.openpgp.PGPCompressedData;
006: import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
007: import org.bouncycastle.openpgp.PGPEncryptedData;
008: import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
009: import org.bouncycastle.openpgp.PGPEncryptedDataList;
010: import org.bouncycastle.openpgp.PGPException;
011: import org.bouncycastle.openpgp.PGPLiteralData;
012: import org.bouncycastle.openpgp.PGPObjectFactory;
013: import org.bouncycastle.openpgp.PGPPBEEncryptedData;
014: import org.bouncycastle.openpgp.PGPUtil;
015:
016: import java.io.ByteArrayOutputStream;
017: import java.io.File;
018: import java.io.FileInputStream;
019: import java.io.FileOutputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.security.NoSuchProviderException;
024: import java.security.SecureRandom;
025: import java.security.Security;
026:
027: /**
028: * A simple utility class that encrypts/decrypts password based
029: * encryption files.
030: * <p>
031: * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.<br>
032: * If -a is specified the output file will be "ascii-armored".<br>
033: * If -i is specified the output file will be "integrity protected".
034: * <p>
035: * To decrypt: PBEFileProcessor -d fileName passPhrase.
036: * <p>
037: * Note: this example will silently overwrite files, nor does it pay any attention to
038: * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
039: * will have been used.
040: */
041: public class PBEFileProcessor {
042: /**
043: * decrypt the passed in message stream
044: */
045: private static void decryptFile(InputStream in, char[] passPhrase)
046: throws Exception {
047: in = PGPUtil.getDecoderStream(in);
048:
049: PGPObjectFactory pgpF = new PGPObjectFactory(in);
050: PGPEncryptedDataList enc;
051: Object o = pgpF.nextObject();
052:
053: //
054: // the first object might be a PGP marker packet.
055: //
056: if (o instanceof PGPEncryptedDataList) {
057: enc = (PGPEncryptedDataList) o;
058: } else {
059: enc = (PGPEncryptedDataList) pgpF.nextObject();
060: }
061:
062: PGPPBEEncryptedData pbe = (PGPPBEEncryptedData) enc.get(0);
063:
064: InputStream clear = pbe.getDataStream(passPhrase, "BC");
065:
066: PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
067:
068: //
069: // if we're trying to read a file generated by someone other than us
070: // the data might not be compressed, so we check the return type from
071: // the factory and behave accordingly.
072: //
073: o = pgpFact.nextObject();
074: if (o instanceof PGPCompressedData) {
075: PGPCompressedData cData = (PGPCompressedData) o;
076:
077: pgpFact = new PGPObjectFactory(cData.getDataStream());
078:
079: o = pgpFact.nextObject();
080: }
081:
082: PGPLiteralData ld = (PGPLiteralData) o;
083:
084: FileOutputStream fOut = new FileOutputStream(ld.getFileName());
085:
086: InputStream unc = ld.getInputStream();
087: int ch;
088:
089: while ((ch = unc.read()) >= 0) {
090: fOut.write(ch);
091: }
092:
093: if (pbe.isIntegrityProtected()) {
094: if (!pbe.verify()) {
095: System.err.println("message failed integrity check");
096: } else {
097: System.err.println("message integrity check passed");
098: }
099: } else {
100: System.err.println("no message integrity check");
101: }
102: }
103:
104: private static void encryptFile(OutputStream out, String fileName,
105: char[] passPhrase, boolean armor, boolean withIntegrityCheck)
106: throws IOException, NoSuchProviderException, PGPException {
107: if (armor) {
108: out = new ArmoredOutputStream(out);
109: }
110:
111: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
112:
113: PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
114: PGPCompressedData.ZIP);
115:
116: PGPUtil.writeFileToLiteralData(comData.open(bOut),
117: PGPLiteralData.BINARY, new File(fileName));
118:
119: comData.close();
120:
121: PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(
122: PGPEncryptedData.CAST5, withIntegrityCheck,
123: new SecureRandom(), "BC");
124:
125: cPk.addMethod(passPhrase);
126:
127: byte[] bytes = bOut.toByteArray();
128:
129: OutputStream cOut = cPk.open(out, bytes.length);
130:
131: cOut.write(bytes);
132:
133: cOut.close();
134:
135: out.close();
136: }
137:
138: public static void main(String[] args) throws Exception {
139: Security.addProvider(new BouncyCastleProvider());
140:
141: if (args[0].equals("-e")) {
142: if (args[1].equals("-a") || args[1].equals("-ai")
143: || args[1].equals("-ia")) {
144: FileOutputStream out = new FileOutputStream(args[2]
145: + ".asc");
146: encryptFile(out, args[2], args[3].toCharArray(), true,
147: (args[1].indexOf('i') > 0));
148: } else if (args[1].equals("-i")) {
149: FileOutputStream out = new FileOutputStream(args[2]
150: + ".bpg");
151: encryptFile(out, args[2], args[3].toCharArray(), false,
152: true);
153: } else {
154: FileOutputStream out = new FileOutputStream(args[1]
155: + ".bpg");
156: encryptFile(out, args[1], args[2].toCharArray(), false,
157: false);
158: }
159: } else if (args[0].equals("-d")) {
160: FileInputStream in = new FileInputStream(args[1]);
161: decryptFile(in, args[2].toCharArray());
162: } else {
163: System.err
164: .println("usage: PBEFileProcessor -e [-ai]|-d file passPhrase");
165: }
166: }
167: }
|