/// <summary> /// PGP Encrypt the file. /// </summary> /// <param name="inputFilePath"></param> /// <param name="outputFilePath"></param> /// <param name="publicKeyFilePath"></param> /// <param name="armor"></param> /// <param name="withIntegrityCheck"></param> public void EncryptFileWithStreamKey(string inputFilePath, string outputFilePath, Stream publicKeyStream, bool armor = true, bool withIntegrityCheck = true) { if (string.IsNullOrEmpty(inputFilePath)) { throw new ArgumentException("inputFilePath"); } if (string.IsNullOrEmpty(outputFilePath)) { throw new ArgumentException("inputFilePath"); } if (!File.Exists(inputFilePath)) { throw new FileNotFoundException(string.Format("Input file [{0}] does not exist.", inputFilePath)); } using (Stream pkStream = publicKeyStream) { using (MemoryStream @out = new MemoryStream()) { if (CompressionAlgorithm != CompressionAlgorithm.Uncompressed) { PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator((CompressionAlgorithmTag)(int)CompressionAlgorithm); PgpUtilities.WriteFileToLiteralData(comData.Open(@out), FileTypeToChar(), new FileInfo(inputFilePath)); comData.Close(); } else { PgpUtilities.WriteFileToLiteralData(@out, FileTypeToChar(), new FileInfo(inputFilePath)); } PgpEncryptedDataGenerator pk = new PgpEncryptedDataGenerator((SymmetricKeyAlgorithmTag)(int)SymmetricKeyAlgorithm, withIntegrityCheck, new SecureRandom()); pk.AddMethod(PGPKeyHelper.ReadPublicKey(pkStream)); byte[] bytes = @out.ToArray(); using (Stream outStream = File.Create(outputFilePath)) { if (armor) { using (ArmoredOutputStream armoredStream = new ArmoredOutputStream(outStream)) { using (Stream armoredOutStream = pk.Open(armoredStream, bytes.Length)) { armoredOutStream.Write(bytes, 0, bytes.Length); } } } else { using (Stream plainStream = pk.Open(outStream, bytes.Length)) { plainStream.Write(bytes, 0, bytes.Length); } } } } } }
/* * PGP decrypt a given stream. */ private void DecryptStream(Stream inputStream, Stream outputStream, Stream privateKeyStream, string passPhrase) { if (inputStream == null) { throw new ArgumentException("InputStream"); } if (outputStream == null) { throw new ArgumentException("outputStream"); } if (privateKeyStream == null) { throw new ArgumentException("privateKeyStream"); } if (passPhrase == null) { passPhrase = string.Empty; } PgpObjectFactory objFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream)); // find secret key PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); PgpObject obj = null; if (objFactory != null) { obj = objFactory.NextPgpObject(); } // the first object might be a PGP marker packet. PgpEncryptedDataList enc = null; if (obj is PgpEncryptedDataList) { enc = (PgpEncryptedDataList)obj; } else { enc = (PgpEncryptedDataList)objFactory.NextPgpObject(); } // decrypt PgpPrivateKey privateKey = null; PgpPublicKeyEncryptedData pbe = null; foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { privateKey = PGPKeyHelper.FindSecretKey(pgpSec, pked.KeyId, passPhrase.ToCharArray()); if (privateKey != null) { pbe = pked; break; } } if (privateKey == null) { throw new ArgumentException("Secret key for message not found."); } PgpObjectFactory plainFact = null; using (Stream clear = pbe.GetDataStream(privateKey)) { plainFact = new PgpObjectFactory(clear); } PgpObject message = plainFact.NextPgpObject(); if (message is PgpOnePassSignatureList) { message = plainFact.NextPgpObject(); } if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory of = null; using (Stream compDataIn = cData.GetDataStream()) { of = new PgpObjectFactory(compDataIn); } message = of.NextPgpObject(); if (message is PgpOnePassSignatureList) { message = of.NextPgpObject(); PgpLiteralData Ld = null; Ld = (PgpLiteralData)message; Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, outputStream); } else { PgpLiteralData Ld = null; Ld = (PgpLiteralData)message; Stream unc = Ld.GetInputStream(); Streams.PipeAll(unc, outputStream); } } else if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; string outFileName = ld.FileName; Stream unc = ld.GetInputStream(); Streams.PipeAll(unc, outputStream); } else if (message is PgpOnePassSignatureList) { throw new PgpException("Encrypted message contains a signed message - not literal data."); } else { throw new PgpException("Message is not a simple encrypted file."); } }