Open() public method

Open a literal data packet for the passed in FileInfo object, returning an output stream for saving the file contents.

The stream created can be closed off by either calling Close() on the stream or Close() on the generator. Closing the returned stream does not close off the Stream parameter outStr.

public Open ( Stream outStr, char format, FileInfo file ) : Stream
outStr Stream The stream we want the packet in.
format char The format we are using.
file System.IO.FileInfo The FileInfo object containg the packet details.
return Stream
Beispiel #1
1
        /// <summary>
        /// Attempt to encrypt a message using PGP with the specified public key(s).
        /// </summary>
        /// <param name="messageStream">Stream containing the message to encrypt.</param>
        /// <param name="encryptedMessageStream">Stream to write the encrypted message into.</param>
        /// <param name="fileName">File name of for the message.</param>
        /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param>
        /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param>
        /// <param name="armor">Whether to wrap the message with ASCII armor.</param>
        /// <returns>Whether the encryption completed successfully.</returns>
        public static bool Encrypt(Stream messageStream, Stream encryptedMessageStream, string fileName, IEnumerable<PgpPublicKey> recipientPublicKeys, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true)
        {
            // Allow any of the corresponding keys to be used for decryption.
            PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(symmetricKeyAlgorithmTag, true, new SecureRandom());
            foreach (PgpPublicKey publicKey in recipientPublicKeys)
            {
                encryptedDataGenerator.AddMethod(publicKey);
            }

            // Handle optional ASCII armor.
            if (armor)
            {
                using (Stream armoredStream = new ArmoredOutputStream(encryptedMessageStream))
                {
                    using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[Constants.LARGEBUFFERSIZE]))
                    {
                        PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                        using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                        {
                            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                            using (Stream literalDataStream = literalDataGenerator.Open(encryptedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                            {
                                messageStream.Seek(0, SeekOrigin.Begin);
                                messageStream.CopyTo(literalDataStream);
                            }
                        }

                    }
                }
            }
            else
            {
                using (Stream encryptedStream = encryptedDataGenerator.Open(encryptedMessageStream, new byte[Constants.LARGEBUFFERSIZE]))
                {
                    PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                    using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                    {
                        PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                        using (Stream literalDataStream = literalDataGenerator.Open(encryptedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                        {
                            messageStream.Seek(0, SeekOrigin.Begin);
                            messageStream.CopyTo(literalDataStream);
                        }
                    }

                }
            }

            return true;
        }
Beispiel #2
1
        /// <summary>
        /// Attempt to encrypt a message using PGP with the specified public key(s).
        /// </summary>
        /// <param name="messageStream">Stream containing the message to encrypt.</param>
        /// <param name="fileName">File name of for the message.</param>
        /// <param name="signedAndEncryptedMessageStream">Stream to write the encrypted message into.</param>
        /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param>
        /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param>
        /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param>
        /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param>
        /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param>
        /// <param name="armor">Whether to wrap the message with ASCII armor.</param>
        /// <returns>Whether the encryption completed successfully.</returns>
        public static bool SignAndEncrypt(Stream messageStream, string fileName, Stream signedAndEncryptedMessageStream, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable<PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true)
        {
            // Create a signature generator.
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(senderPublicKey.Algorithm, hashAlgorithmTag);
            signatureGenerator.InitSign(PgpSignature.BinaryDocument, senderPrivateKey);

            // Add the public key user ID.
            foreach (string userId in senderPublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator signatureSubGenerator = new PgpSignatureSubpacketGenerator();
                signatureSubGenerator.SetSignerUserId(false, userId);
                signatureGenerator.SetHashedSubpackets(signatureSubGenerator.Generate());
                break;
            }

            // Allow any of the corresponding keys to be used for decryption.
            PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes, true, new SecureRandom());
            foreach (PgpPublicKey publicKey in recipientPublicKeys)
            {
                encryptedDataGenerator.AddMethod(publicKey);
            }

            // Handle optional ASCII armor.
            if (armor)
            {
                using (Stream armoredStream = new ArmoredOutputStream(signedAndEncryptedMessageStream))
                {
                    using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[Constants.LARGEBUFFERSIZE]))
                    {
                        PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                        using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                        {
                            signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream);

                            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                            using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary,
                                fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                            {
                                // Process each character in the message.
                                int messageChar;
                                while ((messageChar = messageStream.ReadByte()) >= 0)
                                {
                                    literalStream.WriteByte((byte)messageChar);
                                    signatureGenerator.Update((byte)messageChar);
                                }
                            }

                            signatureGenerator.Generate().Encode(compressedStream);
                        }
                    }
                }
            }
            else
            {
                using (Stream encryptedStream = encryptedDataGenerator.Open(signedAndEncryptedMessageStream, new byte[Constants.LARGEBUFFERSIZE]))
                {
                    PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed);
                    using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream))
                    {
                        signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream);

                        PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
                        using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary,
                            fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE]))
                        {
                            // Process each character in the message.
                            int messageChar;
                            while ((messageChar = messageStream.ReadByte()) >= 0)
                            {
                                literalStream.WriteByte((byte)messageChar);
                                signatureGenerator.Update((byte)messageChar);
                            }
                        }

                        signatureGenerator.Generate().Encode(compressedStream);
                    }
                }
            }

            return true;
        }
Beispiel #3
0
        /// <summary>
        /// 加密并签名
        /// 使用接受方的公钥进行加密
        /// 使用发送方的私钥进行签名
        /// 先压缩,再加密,再签名
        /// </summary>
        /// <param name="kp"></param>
        /// <param name="cfg"></param>
        /// <param name="inputFile"></param>
        /// <param name="outputStream">普通的stream,或者Org.BouncyCastle.Bcpg.ArmoredOutputStream(如果使用加密文件使用ASCII)</param>
        public static void EncryptAndSign(System.IO.FileInfo inputFile, System.IO.Stream outputStream, GpgKeyPair kp, GpgEncryptSignCfg cfg)
        {
            var sr = new Org.BouncyCastle.Security.SecureRandom();
            var pgpEncryptedDataGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpEncryptedDataGenerator(cfg.SymmetricKeyAlgorithmTag, cfg.IntegrityProtected, sr);

            pgpEncryptedDataGenerator.AddMethod(kp.PublickKey);
            var pgpCompressedDataGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpCompressedDataGenerator(cfg.CompressionAlgorithmTag);
            var pgpLiteralDataGenerator    = new Org.BouncyCastle.Bcpg.OpenPgp.PgpLiteralDataGenerator();

            using (var fs = inputFile.OpenRead())
                using (var outputStreamEncrypted = pgpEncryptedDataGenerator.Open(outputStream, new byte[cfg.BufferSize]))
                    using (var outputStreamEncryptedCompressed = pgpCompressedDataGenerator.Open(outputStreamEncrypted))
                        using (var outputStreamEncryptedCompressedLiteral = pgpLiteralDataGenerator.Open(outputStreamEncryptedCompressed,
                                                                                                         Org.BouncyCastle.Bcpg.OpenPgp.PgpLiteralData.Binary, inputFile.Name, inputFile.Length, inputFile.LastWriteTime))
                        {
                            var pgpSignatureGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpSignatureGenerator(kp.PrivateKeySecreted.PublicKey.Algorithm,
                                                                                                                Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha256);
                            pgpSignatureGenerator.InitSign(Org.BouncyCastle.Bcpg.OpenPgp.PgpSignature.BinaryDocument, kp.PrivateKey);
                            var userId = kp.PrivateKeySecreted.PublicKey.GetUserIds().Cast <string>().First();
                            var pgpSignatureSubpacketGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpSignatureSubpacketGenerator();
                            pgpSignatureSubpacketGenerator.SetSignerUserId(cfg.IsCritical, userId);
                            pgpSignatureGenerator.SetHashedSubpackets(pgpSignatureSubpacketGenerator.Generate());
                            pgpSignatureGenerator.GenerateOnePassVersion(cfg.IsNested).Encode(outputStreamEncryptedCompressedLiteral);

                            int dataLenght = 0;
                            var buffer     = new byte[cfg.BufferSize];
                            while ((dataLenght = fs.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                outputStreamEncryptedCompressedLiteral.Write(buffer, 0, dataLenght);
                                pgpSignatureGenerator.Update(buffer, 0, dataLenght);
                            }
                            pgpSignatureGenerator.Generate().Encode(outputStreamEncryptedCompressedLiteral);
                        }
        }
Beispiel #4
0
        public static void WriteFileToLiteralData(Stream output, char fileType, FileInfo file, byte[] buffer)
        {
            PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
            Stream pOut = pgpLiteralDataGenerator.Open(output, fileType, ((FileSystemInfo)file).get_Name(), ((FileSystemInfo)file).get_LastWriteTime(), buffer);

            PipeFileContents(file, pOut, buffer.Length);
        }
		/// <summary>Write out the passed in file as a literal data packet.</summary>
        public static void WriteFileToLiteralData(
            Stream		output,
            char		fileType,
            FileInfo	file)
        {
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
			Stream pOut = lData.Open(output, fileType, file.Name, file.Length, file.LastWriteTime);
			PipeFileContents(file, pOut, 4096);
        }
Beispiel #6
0
        /// <summary>Write out the passed in file as a literal data packet in partial packet format.</summary>
        public static void WriteFileToLiteralData(Stream output, char fileType, FileInfo file, byte[] buffer)
        {
            var lData = new PgpLiteralDataGenerator();

            using (var pOut = lData.Open(output, fileType, file.Name, file.LastWriteTime, buffer))
            {
                PipeFileContents(file, pOut, buffer.Length);
            }
        }
        /// <summary>Write out the passed in file as a literal data packet.</summary>
        public async static Task WriteFileToLiteralData(
            Stream output,
            char fileType,
            StorageFile file)
        {
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
            var props = await file.GetBasicPropertiesAsync();

            Stream pOut = lData.Open(output, fileType, file.Name, (long)props.Size, props.DateModified.DateTime);

            await PipeFileContents(file, pOut, 4096);
        }
    public static Stream PgpEncrypt(this Stream toEncrypt, PgpPublicKey encryptionKey, bool armor = true, bool verify = false)
    {
        var outStream = new MemoryStream();

        var encryptor = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, verify, new SecureRandom());
        var literalizer = new PgpLiteralDataGenerator();
        var compressor = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);

        encryptor.AddMethod(encryptionKey);

        //it would be nice if these streams were read/write, and supported seeking.  Since they are not,
        //we need to shunt the data to a read/write stream so that we can control the flow of data as we go.

        using (var stream = new MemoryStream()) // this is the read/write stream
        using (var armoredStream = armor ? new ArmoredOutputStream(stream) : stream as Stream)
        using (var compressedStream = compressor.Open(armoredStream))
        {
            //data is encrypted first, then compressed, but because of the one-way nature of these streams,
            //other "interim" streams are required.  The raw data is encapsulated in a "Literal" PGP object.
            var rawData = toEncrypt.ReadFully();
            var buffer = new byte[1024];

            using (var literalOut = new MemoryStream())
            using (var literalStream = literalizer.Open(literalOut, PgpLiteralData.Binary, "STREAM", DateTime.UtcNow, buffer))
            {
                literalStream.Write(rawData, 0, rawData.Length);
                literalStream.Close();
                var literalData = literalOut.ReadFully();

                //The literal data object is then encrypted, which flows into the compressing stream and
                //(optionally) into the ASCII armoring stream.
                using (var encryptedStream = encryptor.Open(compressedStream, literalData.Length))
                {
                    encryptedStream.Write(literalData, 0, literalData.Length);
                    encryptedStream.Close();
                    compressedStream.Close();
                    armoredStream.Close();

                    //the stream processes are now complete, and our read/write stream is now populated with
                    //encrypted data.  Convert the stream to a byte array and write to the out stream.
                    stream.Position = 0;
                    var data = stream.ReadFully();
                    outStream.Write(data, 0, data.Length);
                }
            }
        }

        outStream.Position = 0;

        return outStream;
    }
Beispiel #9
0
        /// <summary>Write out the passed in file as a literal data packet in partial packet format.</summary>
        public static void WriteFileToLiteralData(
            Stream outputStream,
            char fileType,
            FileInfo file,
            byte[]              buffer)
        {
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
            Stream     pOut        = lData.Open(outputStream, fileType, file.Name, file.LastWriteTime, buffer);
            FileStream inputStream = file.OpenRead();

            byte[] buf = new byte[buffer.Length];

            int len;

            while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
            {
                pOut.Write(buf, 0, len);
            }

            lData.Close();
            inputStream.Close();
        }
Beispiel #10
0
        /// <summary>
        /// 加密文件
        /// 使用接收方的公钥加密文件
        /// 先压缩,再加密,
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="outputStream">普通的stream,或者Org.BouncyCastle.Bcpg.ArmoredOutputStream(如果使用加密文件使用ASCII)</param>
        /// <param name="pubKey"></param>
        /// <param name="cfg"></param>
        public static void Encrypt(System.IO.FileInfo inputFile, System.IO.Stream outputStream, System.IO.Stream publickKeyStream, GpgEncryptSignCfg cfg)
        {
            var sr = new Org.BouncyCastle.Security.SecureRandom();
            var pgpEncryptedDataGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpEncryptedDataGenerator(cfg.SymmetricKeyAlgorithmTag, cfg.IntegrityProtected, sr);
            var pubKey = GpgKeyPair.ReadPublicKey(publickKeyStream);

            pgpEncryptedDataGenerator.AddMethod(pubKey);
            var pgpCompressedDataGenerator = new Org.BouncyCastle.Bcpg.OpenPgp.PgpCompressedDataGenerator(cfg.CompressionAlgorithmTag);
            var pgpLiteralDataGenerator    = new Org.BouncyCastle.Bcpg.OpenPgp.PgpLiteralDataGenerator();

            using (var fs = inputFile.OpenRead())
                using (var outputStreamEncrypted = pgpEncryptedDataGenerator.Open(outputStream, new byte[cfg.BufferSize]))
                    using (var outputStreamEncryptedCompressed = pgpCompressedDataGenerator.Open(outputStreamEncrypted))
                        using (var outputStreamEncryptedCompressedLiteral = pgpLiteralDataGenerator.Open(outputStreamEncryptedCompressed,
                                                                                                         Org.BouncyCastle.Bcpg.OpenPgp.PgpLiteralData.Binary, inputFile.Name, inputFile.Length, inputFile.LastWriteTime))
                        {
                            int dataLenght = 0;
                            var buffer     = new byte[cfg.BufferSize];
                            while ((dataLenght = fs.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                outputStreamEncryptedCompressedLiteral.Write(buffer, 0, dataLenght);
                            }
                        }
        }
        /**
        * Generate an encapsulated signed file.
        *
        * @param fileName
        * @param keyIn
        * @param outputStream
        * @param pass
        * @param armor
        */
        private static void SignFile(
            string	fileName,
            Stream	keyIn,
            Stream	outputStream,
            char[]	pass,
            bool	armor,
			bool	compress)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }

            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            foreach (string userId in pgpSec.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, userId);
                sGen.SetHashedSubpackets(spGen.Generate());
                // Just the first one!
                break;
            }

            Stream cOut = outputStream;
			PgpCompressedDataGenerator cGen = null;
			if (compress)
			{
				cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);

				cOut = cGen.Open(cOut);
			}

			BcpgOutputStream bOut = new BcpgOutputStream(cOut);

            sGen.GenerateOnePassVersion(false).Encode(bOut);

            FileInfo					file = new FileInfo(fileName);
            PgpLiteralDataGenerator     lGen = new PgpLiteralDataGenerator();
            Stream						lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);
            FileStream					fIn = file.OpenRead();
            int                         ch = 0;

			while ((ch = fIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte) ch);
                sGen.Update((byte)ch);
            }

			fIn.Close();
			lGen.Close();

			sGen.Generate().Encode(bOut);

			if (cGen != null)
			{
				cGen.Close();
			}

			if (armor)
			{
				outputStream.Close();
			}
        }
Beispiel #12
0
        private static Stream ChainLiteralOut(Stream compressedOut, FileInfo file)
        {
            PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();

            return pgpLiteralDataGenerator.Open(compressedOut, PgpLiteralData.Binary, file);
        }
		/// <summary>Write out the passed in file as a literal data packet in partial packet format.</summary>
        public static void WriteFileToLiteralData(
            Stream		output,
            char		fileType,
            FileInfo	file,
            byte[]		buffer)
        {
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
            Stream pOut = lData.Open(output, fileType, file.Name, file.LastWriteTime, buffer);
			PipeFileContents(file, pOut, buffer.Length);
        }
Beispiel #14
0
    /// <summary>
    /// Encrypt string using a PGP public key
    /// </summary>
    /// <param name="plain">plain text to encrypt</param>
    /// <param name="armoredPublicKey">public key in ASCII "-----BEGIN PGP PUBLIC KEY BLOCK----- .. -----END PGP PUBLIC KEY BLOCK-----" format</param>
    /// <returns>PGP message string</returns>
    public static string PGPEncrypt(string plain, string armoredPublicKey)
    {
      // encode data
      byte[] data = Encoding.UTF8.GetBytes(plain);

      // create the WinAuth public key
      PgpPublicKey publicKey = null;
      using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(armoredPublicKey)))
      {
        using (Stream dis = PgpUtilities.GetDecoderStream(ms))
        {
          PgpPublicKeyRingBundle bundle = new PgpPublicKeyRingBundle(dis);
          foreach (PgpPublicKeyRing keyring in bundle.GetKeyRings())
          {
            foreach (PgpPublicKey key in keyring.GetPublicKeys())
            {
              if (key.IsEncryptionKey == true && key.IsRevoked() == false)
              {
                publicKey = key;
                break;
              }
            }
          }
        }
      }

      // encrypt the data using PGP
      using (MemoryStream encryptedStream = new MemoryStream())
      {
        using (ArmoredOutputStream armored = new ArmoredOutputStream(encryptedStream))
        {
          PgpEncryptedDataGenerator pedg = new PgpEncryptedDataGenerator(Org.BouncyCastle.Bcpg.SymmetricKeyAlgorithmTag.Cast5, true, new Org.BouncyCastle.Security.SecureRandom());
          pedg.AddMethod(publicKey);
          using (Stream pedgStream = pedg.Open(armored, new byte[4096]))
          {
            PgpCompressedDataGenerator pcdg = new PgpCompressedDataGenerator(Org.BouncyCastle.Bcpg.CompressionAlgorithmTag.Zip);
            using (Stream pcdgStream = pcdg.Open(pedgStream))
            {
              PgpLiteralDataGenerator pldg = new PgpLiteralDataGenerator();
              using (Stream encrypter = pldg.Open(pcdgStream, PgpLiteralData.Binary, "", (long)data.Length, DateTime.Now))
              {
                encrypter.Write(data, 0, data.Length);
              }
            }
          }
        }

        return Encoding.ASCII.GetString(encryptedStream.ToArray());
      }
    }
        /**
         * Generates an encapsulated signed file.
         */
        public void signMessage(Stream unsignedContent, Stream signedContent, bool armor)
        {
            if (armor) {
                // output will be BASE64 encoded
                signedContent = new ArmoredOutputStream(signedContent);
            }

            PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);
            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();
            try {
                BcpgOutputStream bcpgSignedContentOut = new BcpgOutputStream(compressedDataGenerator.Open(signedContent));

                PgpPrivateKey pgpPrivateKey = secretKeyForSigning.ExtractPrivateKey(secretKeyPassword);
                PgpSignatureGenerator signatureGenerator = createSignatureGenerator(pgpPrivateKey);

                signatureGenerator.GenerateOnePassVersion(false).Encode(bcpgSignedContentOut);

                Stream literalDataOut = literalDataGenerator.Open(bcpgSignedContentOut, PgpLiteralData.Binary, "_CONSOLE", unsignedContent.Length, DateTime.Now);

                updateSignatureGeneratorWithInputBytes(unsignedContent, signatureGenerator, literalDataOut);
                signatureGenerator.Generate().Encode(bcpgSignedContentOut);
            } finally {
                literalDataGenerator.Close();
                compressedDataGenerator.Close();
                signedContent.Close();
            }
        }
 private void writeClearDataToByteOut(PgpCompressedDataGenerator compressedDataGenerator, PgpLiteralDataGenerator literalDataGenerator, byte[] clearData, Stream byteOut)
 {
     try {
         Stream pOut = literalDataGenerator.Open(compressedDataGenerator.Open(byteOut), // the compressed output stream
                   PgpLiteralData.Binary,
                   PgpLiteralData.Text.ToString(),  // "filename" to store
                   clearData.Length, // length of clear data
                   DateTime.Now // current time
         );
         pOut.Write(clearData, 0, clearData.Length);
     } finally {
         literalDataGenerator.Close();
     }
 }
		static Stream Compress (Stream content)
		{
			var compresser = new PgpCompressedDataGenerator (CompressionAlgorithmTag.ZLib);
			var memory = new MemoryBlockStream ();

			using (var compressed = compresser.Open (memory)) {
				var literalGenerator = new PgpLiteralDataGenerator ();

				using (var literal = literalGenerator.Open (compressed, 't', "mime.txt", content.Length, DateTime.Now)) {
					content.CopyTo (literal, 4096);
					literal.Flush ();
				}

				compressed.Flush ();
			}

			memory.Position = 0;

			return memory;
		}
        /// <summary>
        /// Encrypt data to a set of recipients
        /// </summary>
        /// <param name="data">Data to encrypt</param>
        /// <param name="recipients">List of email addresses</param>
        /// <param name="recipients">Headers to add to ascii armor</param>
        /// <returns>Returns ascii armored encrypted data</returns>
        public string Encrypt(byte[] data, IList<string> recipients, Dictionary<string, string> headers)
        {
            Context = new CryptoContext(Context);

            var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
            var literalData = new PgpLiteralDataGenerator();
            var cryptData = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, new SecureRandom());

            foreach (var recipient in recipients)
            {
                var recipientKey = GetPublicKeyForEncryption(recipient);
                if (recipientKey == null)
                    throw new PublicKeyNotFoundException("Error, unable to find recipient key \"" + recipient + "\".");

                cryptData.AddMethod(recipientKey);
            }

            using (var sout = new MemoryStream())
            {
                using (var armoredOut = new ArmoredOutputStream(sout))
                {
                    foreach(var header in headers)
                        armoredOut.SetHeader(header.Key, header.Value);

                    using (var clearOut = new MemoryStream())
                    {
                        using (var compressedOut = compressedData.Open(clearOut))
                        using (var literalOut = literalData.Open(
                            compressedOut,
                            PgpLiteralData.Binary,
                            "email",
                            data.Length,
                            DateTime.UtcNow))
                        {
                            literalOut.Write(data, 0, data.Length);
                        }

                        var clearData = clearOut.ToArray();

                        using (var encryptOut = cryptData.Open(armoredOut, clearData.Length))
                        {
                            encryptOut.Write(clearData, 0, clearData.Length);
                        }
                    }
                }

                return ASCIIEncoding.ASCII.GetString(sout.ToArray());
            }
        }
		/// <summary>
		/// Cryptographically signs and encrypts the specified content for the specified recipients.
		/// </summary>
		/// <remarks>
		/// Cryptographically signs and encrypts the specified content for the specified recipients.
		/// </remarks>
		/// <returns>A new <see cref="MimeKit.MimePart"/> instance
		/// containing the encrypted data.</returns>
		/// <param name="signer">The signer.</param>
		/// <param name="digestAlgo">The digest algorithm to use for signing.</param>
		/// <param name="cipherAlgo">The encryption algorithm.</param>
		/// <param name="recipients">The recipients.</param>
		/// <param name="content">The content.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="signer"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="recipients"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="content"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="signer"/> cannot be used for signing.</para>
		/// <para>-or-</para>
		/// <para>One or more of the recipient keys cannot be used for encrypting.</para>
		/// <para>-or-</para>
		/// <para>No recipients were specified.</para>
		/// </exception>
		/// <exception cref="System.NotSupportedException">
		/// The specified encryption algorithm is not supported.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The user chose to cancel the password prompt.
		/// </exception>
		/// <exception cref="System.UnauthorizedAccessException">
		/// 3 bad attempts were made to unlock the secret key.
		/// </exception>
		public MimePart SignAndEncrypt (PgpSecretKey signer, DigestAlgorithm digestAlgo, EncryptionAlgorithm cipherAlgo, IEnumerable<PgpPublicKey> recipients, Stream content)
		{
			// TODO: document the exceptions that can be thrown by BouncyCastle

			if (signer == null)
				throw new ArgumentNullException ("signer");

			if (!signer.IsSigningKey)
				throw new ArgumentException ("The specified secret key cannot be used for signing.", "signer");

			if (recipients == null)
				throw new ArgumentNullException ("recipients");

			if (content == null)
				throw new ArgumentNullException ("content");

			var encrypter = new PgpEncryptedDataGenerator (GetSymmetricKeyAlgorithm (cipherAlgo), true);
			var hashAlgorithm = GetHashAlgorithm (digestAlgo);
			int count = 0;

			foreach (var recipient in recipients) {
				if (!recipient.IsEncryptionKey)
					throw new ArgumentException ("One or more of the recipient keys cannot be used for encrypting.", "recipients");

				encrypter.AddMethod (recipient);
				count++;
			}

			if (count == 0)
				throw new ArgumentException ("No recipients specified.", "recipients");

			var compresser = new PgpCompressedDataGenerator (CompressionAlgorithmTag.ZLib);

			using (var compressed = new MemoryBlockStream ()) {
				using (var signed = compresser.Open (compressed)) {
					var signatureGenerator = new PgpSignatureGenerator (signer.PublicKey.Algorithm, hashAlgorithm);
					signatureGenerator.InitSign (PgpSignature.CanonicalTextDocument, GetPrivateKey (signer));
					var subpacket = new PgpSignatureSubpacketGenerator ();

					foreach (string userId in signer.PublicKey.GetUserIds ()) {
						subpacket.SetSignerUserId (false, userId);
						break;
					}

					signatureGenerator.SetHashedSubpackets (subpacket.Generate ());

					var onepass = signatureGenerator.GenerateOnePassVersion (false);
					onepass.Encode (signed);

					var literalGenerator = new PgpLiteralDataGenerator ();
					using (var literal = literalGenerator.Open (signed, 't', "mime.txt", content.Length, DateTime.Now)) {
						var buf = new byte[4096];
						int nread;

						while ((nread = content.Read (buf, 0, buf.Length)) > 0) {
							signatureGenerator.Update (buf, 0, nread);
							literal.Write (buf, 0, nread);
						}

						literal.Flush ();
					}

					var signature = signatureGenerator.Generate ();
					signature.Encode (signed);

					signed.Flush ();
				}

				compressed.Position = 0;

				var memory = new MemoryBlockStream ();
				using (var armored = new ArmoredOutputStream (memory)) {
					using (var encrypted = encrypter.Open (armored, compressed.Length)) {
						compressed.CopyTo (encrypted, 4096);
						encrypted.Flush ();
					}

					armored.Flush ();
				}

				memory.Position = 0;

				return new MimePart ("application", "octet-stream") {
					ContentDisposition = new ContentDisposition ("attachment"),
					ContentObject = new ContentObject (memory)
				};
			}
		}
        public static void SignAndEncryptFile(string actualFileName, string embeddedFileName,
             Stream privateKeyStream, string passPhrase, Stream publicKeyStream,
             bool armor, bool withIntegrityCheck, Stream outputStream)
        {
            const int BUFFER_SIZE = 1 << 16; // should always be power of 2

            if (armor)
                outputStream = new ArmoredOutputStream(outputStream);

            PgpPublicKey pubKey = ReadPublicKey(publicKeyStream);

            // Init encrypted data generator
            PgpEncryptedDataGenerator encryptedDataGenerator =
                new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
            encryptedDataGenerator.AddMethod(pubKey);
            Stream encryptedOut = encryptedDataGenerator.Open(outputStream, new byte[BUFFER_SIZE]);

            // Init compression
            PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
            Stream compressedOut = compressedDataGenerator.Open(encryptedOut);

            // Init signature
            PgpSecretKeyRingBundle pgpSecBundle = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

            var pgpSecKey = ReadSecretKey(pgpSecBundle);
            if (pgpSecKey == null)
                throw new ArgumentException(pubKey.KeyId.ToString("X") + " could not be found in specified key ring bundle.", "keyId");

            PgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(passPhrase.ToCharArray());
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
            signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            var userIds = pgpSecKey.PublicKey.GetUserIds();

            string userId = null;
            foreach (string value in userIds)
            {
                // Just the first one!
                userId = value;
                break;
            }

            if (string.IsNullOrEmpty(userId))
            {
                throw new ArgumentException(string.Format("Can't find userId in signing key. KeyId '{0}'.", pubKey.KeyId.ToString("X")));
            }

            PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
            spGen.SetSignerUserId(false, userId);
            signatureGenerator.SetHashedSubpackets(spGen.Generate());

            signatureGenerator.GenerateOnePassVersion(false).Encode(compressedOut);

            // Create the Literal Data generator output stream
            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();

            // NOTE: Commented this out because it uses FileInfo to get stats on files and won't work properly

            FileInfo embeddedFile = new FileInfo(embeddedFileName);
            FileInfo actualFile = new FileInfo(actualFileName);

            if (!actualFile.Exists)
            {
                throw new FileNotFoundException(actualFile.FullName);
            }

            // TODO: Use lastwritetime from source file
            Stream literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, embeddedFile.Name, actualFile.LastWriteTime, new byte[BUFFER_SIZE]);

            // Open the input file
            FileStream inputStream = actualFile.OpenRead();

            byte[] buf = new byte[BUFFER_SIZE];
            int len;
            while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
            {
                literalOut.Write(buf, 0, len);
                signatureGenerator.Update(buf, 0, len);
            }

            literalOut.Close();
            literalDataGenerator.Close();
            signatureGenerator.Generate().Encode(compressedOut);
            compressedOut.Close();
            compressedDataGenerator.Close();
            encryptedOut.Close();
            encryptedDataGenerator.Close();
            inputStream.Close();

            if (armor)
                outputStream.Close();
        }
        /// <summary>
        /// Sign data using key
        /// </summary>
        /// <param name="data">Data to sign</param>
        /// <param name="key">Email address of key</param>
        /// <returns>Returns ascii armored signature</returns>
        public string Sign(byte[] data, string key, Dictionary<string, string> headers)
        {
            Context = new CryptoContext(Context);

            var senderKey = GetSecretKeyForSigning(key);
            if (senderKey == null)
                throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\".");

            var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
            var literalData = new PgpLiteralDataGenerator();

            // Setup signature stuff //
            var tag = senderKey.PublicKey.Algorithm;
            var signatureData = new PgpSignatureGenerator(tag, HashAlgorithmTag.Sha256);
            signatureData.InitSign(PgpSignature.BinaryDocument, senderKey.ExtractPrivateKey(Context.Password));

            foreach (string userId in senderKey.PublicKey.GetUserIds())
            {
                var subPacketGenerator = new PgpSignatureSubpacketGenerator();

                subPacketGenerator.SetSignerUserId(false, userId);
                signatureData.SetHashedSubpackets(subPacketGenerator.Generate());

                // Just the first one!
                break;
            }
            // //

            using (var sout = new MemoryStream())
            {
                using (var armoredOut = new ArmoredOutputStream(sout))
                {
                    foreach (var header in headers)
                        armoredOut.SetHeader(header.Key, header.Value);

                    using (var compressedOut = compressedData.Open(armoredOut))
                    using (var outputStream = new BcpgOutputStream(compressedOut))
                    {
                        signatureData.GenerateOnePassVersion(false).Encode(outputStream);

                        using (var literalOut = literalData.Open(outputStream, 'b', "", data.Length, DateTime.Now))
                        {
                            literalOut.Write(data, 0, data.Length);
                            signatureData.Update(data);
                        }

                        signatureData.Generate().Encode(outputStream);
                    }
                }

                return ASCIIEncoding.ASCII.GetString(sout.ToArray());
            }
        }
Beispiel #22
0
		/// <summary>Write out the passed in file as a literal data packet in partial packet format.</summary>
        public static void WriteFileToLiteralData(
            Stream		outputStream,
            char		fileType,
            FileInfo	file,
            byte[]		buffer)
        {
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
            Stream pOut = lData.Open(outputStream, fileType, file.Name, file.LastWriteTime, buffer);
            FileStream inputStream = file.OpenRead();
            byte[] buf = new byte[buffer.Length];

			int len;
            while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
            {
                pOut.Write(buf, 0, len);
            }

			lData.Close();
            inputStream.Close();
        }
        /// <summary>
        /// Signs then encrypts data using key and list of recipients.
        /// </summary>
        /// <param name="data">Data to encrypt</param>
        /// <param name="key">Signing key</param>
        /// <param name="recipients">List of keys to encrypt to</param>
        /// <returns>Returns ascii armored signed/encrypted data</returns>
        protected string SignAndEncrypt(byte[] data, string key, IList<string> recipients, Dictionary<string, string> headers, bool isBinary)
        {
            Context = new CryptoContext(Context);

            var senderKey = GetSecretKeyForEncryption(key);
            if (senderKey == null)
                throw new SecretKeyNotFoundException("Error, Unable to locate sender encryption key \"" + key + "\".");

            var senderSignKey = GetSecretKeyForSigning(key);
            if (senderSignKey == null)
                throw new SecretKeyNotFoundException("Error, Unable to locate sender signing key \"" + key + "\".");

            var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);
            var literalData = new PgpLiteralDataGenerator();
            var cryptData = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, new SecureRandom());

            foreach (var recipient in recipients)
            {
                var recipientKey = GetPublicKeyForEncryption(recipient);
                if (recipientKey == null)
                    throw new PublicKeyNotFoundException("Error, unable to find recipient key \"" + recipient + "\".");

                cryptData.AddMethod(recipientKey);
            }

            // Setup signature stuff //
            var signatureData = new PgpSignatureGenerator(
                senderSignKey.PublicKey.Algorithm,
                HashAlgorithmTag.Sha256);
            signatureData.InitSign(
                isBinary ? PgpSignature.BinaryDocument : PgpSignature.CanonicalTextDocument,
                senderSignKey.ExtractPrivateKey(Context.Password));

            foreach (string userId in senderKey.PublicKey.GetUserIds())
            {
                var subPacketGenerator = new PgpSignatureSubpacketGenerator();

                subPacketGenerator.SetSignerUserId(false, userId);
                signatureData.SetHashedSubpackets(subPacketGenerator.Generate());

                // Just the first one!
                break;
            }
            // //

            using (var sout = new MemoryStream())
            {
                using (var armoredOut = new ArmoredOutputStream(sout))
                {
                    foreach (var header in headers)
                        armoredOut.SetHeader(header.Key, header.Value);

                    using (var clearOut = new MemoryStream())
                    {
                        using (var compressedOut = compressedData.Open(clearOut))
                        {
                            signatureData.GenerateOnePassVersion(false).Encode(compressedOut);

                            using (var literalOut = literalData.Open(
                                compressedOut,
                                isBinary ? PgpLiteralData.Binary : PgpLiteralData.Text,
                                "",
                                data.Length,
                                DateTime.UtcNow))
                            {
                                literalOut.Write(data, 0, data.Length);
                                signatureData.Update(data, 0, data.Length);
                            }

                            signatureData.Generate().Encode(compressedOut);
                        }

                        var clearData = clearOut.ToArray();

                        using (var encryptOut = cryptData.Open(armoredOut, clearData.Length))
                        {
                            encryptOut.Write(clearData, 0, clearData.Length);
                        }
                    }
                }

                return ASCIIEncoding.ASCII.GetString(sout.ToArray());
            }
        }
        //public static string GetPrivateKeyXml(string inputData)
        //{
        //    Stream inputStream = StreamHelper.GetStream(inputData);
        //    PgpObjectFactory pgpFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
        //    PgpObject pgp = null;
        //    if (pgpFactory != null)
        //    {
        //        pgp = pgpFactory.NextPgpObject();
        //    }

        //    PgpEncryptedDataList encryptedData = null;
        //    if (pgp is PgpEncryptedDataList)
        //    {
        //        encryptedData = (PgpEncryptedDataList)pgp;
        //    }
        //    else
        //    {
        //        encryptedData = (PgpEncryptedDataList)pgpFactory.NextPgpObject();
        //    }

        //    Stream privateKeyStream = File.OpenRead(PrivateKeyOnlyPath);

        //    // find secret key
        //    PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));
        //    PgpPrivateKey privateKey = null;

        //    foreach (PgpPublicKeyEncryptedData pked in encryptedData.GetEncryptedDataObjects())
        //    {
        //        privateKey = FindSecretKey(pgpKeyRing, pked.KeyId, Password.ToCharArray());
        //        if (privateKey != null)
        //        {
        //            //pubKeyData = pked;
        //            break;
        //        }
        //    }

        //    // get xml:
        //    RsaPrivateCrtKeyParameters rpckp = ((RsaPrivateCrtKeyParameters)privateKey.Key);
        //    RSAParameters dotNetParams = DotNetUtilities.ToRSAParameters(rpckp);
        //    RSA rsa = RSA.Create();
        //    rsa.ImportParameters(dotNetParams);
        //    string xmlPrivate = rsa.ToXmlString(true);

        //    return xmlPrivate;
        //}

        #endregion

        #region helpers

        /// <summary>
        /// 
        /// </summary>
        /// <param name="clearData"></param>
        /// <param name="fileName">File name reference for compression to include (not fully qualified).</param>
        /// <param name="algorithm"></param>
        /// <returns></returns>
        private static byte[] Compress(byte[] clearData, string fileName, CompressionAlgorithmTag algorithm)
        {
            MemoryStream bOut = new MemoryStream();

            PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
            Stream cos = comData.Open(bOut); // open it with the final destination
            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();

            // we want to Generate compressed data. This might be a user option later,
            // in which case we would pass in bOut.
            Stream pOut = lData.Open(
            cos,                    // the compressed output stream
            PgpLiteralData.Binary,
            fileName,               // "filename" to store
            clearData.Length,       // length of clear data
            DateTime.UtcNow         // current time
            );

            pOut.Write(clearData, 0, clearData.Length);
            pOut.Close();

            comData.Close();

            return bOut.ToArray();
        }
 /// <summary>Write out the passed in file as a literal data packet.</summary>
 public static void WriteFileToLiteralData(Stream output, char fileType, FileInfo file)
 {
     var lData = new PgpLiteralDataGenerator();
     using (var pOut = lData.Open(output, fileType, file.Name, file.Length, file.LastWriteTime))
     {
         PipeFileContents(file, pOut, 4096);
     }
 }