using System; using System.IO; using Org.BouncyCastle.Bcpg.OpenPgp; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples { /** * A simple utility class that encrypts/decrypts password based * encryption files. *

* To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.
* If -a is specified the output file will be "ascii-armored".
* If -i is specified the output file will be "integrity protected".

*

* To decrypt: PBEFileProcessor -d fileName passPhrase.

*

* Note: this example will silently overwrite files, nor does it pay any attention to * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase * will have been used.

*/ public sealed class PbeFileProcessor { private PbeFileProcessor() {} private static void DecryptFile(string inputFileName, char[] passPhrase) { using (Stream input = File.OpenRead(inputFileName)) { DecryptFile(input, passPhrase); } } /** * decrypt the passed in message stream */ private static void DecryptFile( Stream inputStream, char[] passPhrase) { inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpObject o = pgpF.NextPgpObject(); // // the first object might be a PGP marker packet. // PgpEncryptedDataList enc = o as PgpEncryptedDataList; if (enc == null) { enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); } PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0]; Stream clear = pbe.GetDataStream(passPhrase); PgpObjectFactory pgpFact = new PgpObjectFactory(clear); // // if we're trying to read a file generated by someone other than us // the data might not be compressed, so we check the return type from // the factory and behave accordingly. // o = pgpFact.NextPgpObject(); if (o is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData) o; pgpFact = new PgpObjectFactory(cData.GetDataStream()); o = pgpFact.NextPgpObject(); } PgpLiteralData ld = (PgpLiteralData) o; Stream unc = ld.GetInputStream(); Stream fOut = File.Create(ld.FileName); Streams.PipeAll(unc, fOut); fOut.Close(); if (pbe.IsIntegrityProtected()) { if (!pbe.Verify()) { Console.Error.WriteLine("message failed integrity check"); } else { Console.Error.WriteLine("message integrity check passed"); } } else { Console.Error.WriteLine("no message integrity check"); } } private static void EncryptFile( string outputFileName, string inputFileName, char[] passPhrase, bool armor, bool withIntegrityCheck) { using (Stream output = File.Create(outputFileName)) { EncryptFile(output, inputFileName, passPhrase, armor, withIntegrityCheck); } } private static void EncryptFile( Stream outputStream, string fileName, char[] passPhrase, bool armor, bool withIntegrityCheck) { if (armor) { outputStream = new ArmoredOutputStream(outputStream); } try { byte[] compressedData = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip); PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); encGen.AddMethod(passPhrase, HashAlgorithmTag.Sha1); Stream encOut = encGen.Open(outputStream, compressedData.Length); encOut.Write(compressedData, 0, compressedData.Length); encOut.Close(); if (armor) { outputStream.Close(); } } catch (PgpException e) { Console.Error.WriteLine(e); Exception underlyingException = e.InnerException; if (underlyingException != null) { Console.Error.WriteLine(underlyingException.Message); Console.Error.WriteLine(underlyingException.StackTrace); } } } public static void Main( string[] args) { if (args[0].Equals("-e")) { if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia")) { EncryptFile(args[2] + ".asc", args[2], args[3].ToCharArray(), true, (args[1].IndexOf('i') > 0)); } else if (args[1].Equals("-i")) { EncryptFile(args[2] + ".bpg", args[2], args[3].ToCharArray(), false, true); } else { EncryptFile(args[1] + ".bpg", args[1], args[2].ToCharArray(), false, false); } } else if (args[0].Equals("-d")) { DecryptFile(args[1], args[2].ToCharArray()); } else { Console.Error.WriteLine("usage: PbeFileProcessor -e [-ai]|-d file passPhrase"); } } } }