充气城堡加密

时间:2013-04-26 11:46:25

标签: c# encryption bouncycastle public-key-encryption pgp

我有要求将PGP加密的CSV文件发送到SFTP,我对PGP一无所知。经过大量研究后,我可以使用“Bouncy Castle' Library在互联网上找到以下代码。代码似乎是gogod,但由于我对PGP缺乏经验,对我来说不起作用。请帮助我找到正确的值:

  1. publicKeyFileName
  2. privateKeyFileName
  3. pasPhrase
  4. 以下是我的代码:

    namespace PgpEncryption
    {
        class Program
        {
            public static void Main()
            {
                EncryptAndSign();
            }
    
            private static void EncryptAndSign()
            {
                string publicKeyFileName = "";
                string privateKeyFileName = "";
                string pasPhrase = "";    
                PgpEncryptionKeys encryptionKeys
                    = new PgpEncryptionKeys(publicKeyFileName, privateKeyFileName, pasPhrase);
                PgpEncrypt encrypter = new PgpEncrypt(encryptionKeys);
                string encryptedFileName = "";
                using (Stream outputStream = File.Create(encryptedFileName))
                {
                    string fileToEncrypt = "";    
                    encrypter.EncryptAndSign(outputStream, new FileInfo(fileToEncrypt));
                }    
            }
        }
    }
    
    public class PgpEncryptionKeys
    {
        public PgpEncryptionKeys(string publicKeyPath, string privateKeyPath, string passPhrase)
        {
            if (!File.Exists(publicKeyPath))
                throw new ArgumentException("Public key file not found", "publicKeyPath");
            if (!File.Exists(privateKeyPath))
                throw new ArgumentException("Private key file not found", "privateKeyPath");
            if (String.IsNullOrEmpty(passPhrase))
                throw new ArgumentException("passPhrase is null or empty.", "passPhrase");
            PublicKey = ReadPublicKey(publicKeyPath);
            SecretKey = ReadSecretKey(privateKeyPath);
            PrivateKey = ReadPrivateKey(passPhrase);
        }
    
        #region Secret Key
        private PgpSecretKey ReadSecretKey(string privateKeyPath)
        {
            using (Stream keyIn = File.OpenRead(privateKeyPath))
            using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
            {
                PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);
                PgpSecretKey foundKey = GetFirstSecretKey(secretKeyRingBundle);
                if (foundKey != null)
                    return foundKey;              
            }
            throw new ArgumentException("Can't find signing key in key ring.");
        }
    
        private PgpSecretKey GetFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle)
        {
           foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
            {
                PgpSecretKey key = (PgpSecretKey)kRing.GetSecretKeys();
                if (key != null)
                    return key;
            }
            return null;
        }
        #endregion
    
        #region Public Key
        private PgpPublicKey ReadPublicKey(string publicKeyPath)
        {
            using (Stream keyIn = File.OpenRead(publicKeyPath))
            using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
            {
                PgpPublicKeyRingBundle publicKeyRingBundle = new PgpPublicKeyRingBundle(inputStream);
                PgpPublicKey foundKey = GetFirstPublicKey(publicKeyRingBundle);
                if (foundKey != null)
                    return foundKey;
            }
            throw new ArgumentException("No encryption key found in public key ring.");
        }
    
        private PgpPublicKey GetFirstPublicKey(PgpPublicKeyRingBundle publicKeyRingBundle)
        {
            foreach (PgpPublicKeyRing kRing in publicKeyRingBundle.GetKeyRings())
            {
                PgpPublicKey key = (PgpPublicKey)kRing.GetPublicKeys();
                //PgpPublicKey key = kRing.GetPublicKeys()
                                    //.Cast<PgpPublicKey>()
                                    // .Where(k => k.IsEncryptionKey)
                                    //  .FirstOrDefault();
                if (key != null)
                    return key;
            }
            return null;
        }
        #endregion
    
        #region Private Key
        private PgpPrivateKey ReadPrivateKey(string passPhrase)
        {
            PgpPrivateKey privateKey = SecretKey.ExtractPrivateKey(passPhrase.ToCharArray());
            if (privateKey != null)
                return privateKey;
            throw new ArgumentException("No private key found in secret key.");
        }
        #endregion        
    }
    
    
    public class PgpEncrypt
    {
    
        private PgpEncryptionKeys m_encryptionKeys;
        private const int BufferSize = 0x10000; // should always be power of 2  
    
        /// <summary>
        /// Instantiate a new PgpEncrypt class with initialized PgpEncryptionKeys.
        /// </summary>
        /// <param name="encryptionKeys"></param>
        /// <exception cref="ArgumentNullException">encryptionKeys is null</exception>
        public PgpEncrypt(PgpEncryptionKeys encryptionKeys)
        {
    
            if (encryptionKeys == null)
    
                throw new ArgumentNullException("encryptionKeys", "encryptionKeys is null.");
            m_encryptionKeys = encryptionKeys;
        }
    
        /// <summary>
        /// Encrypt and sign the file pointed to by unencryptedFileInfo and 
        /// write the encrypted content to outputStream.
        /// </summary>
        /// <param name="outputStream">The stream that will contain the 
        /// encrypted data when this method returns.</param>
        /// <param name="fileName">FileInfo of the file to encrypt</param>
        public void EncryptAndSign(Stream outputStream, FileInfo unencryptedFileInfo)
        {
            if (outputStream == null)
                throw new ArgumentNullException("outputStream", "outputStream is null.");
            if (unencryptedFileInfo == null)
                throw new ArgumentNullException("unencryptedFileInfo", "unencryptedFileInfo is null.");
            if (!File.Exists(unencryptedFileInfo.FullName))
                throw new ArgumentException("File to encrypt not found.");
            using (Stream encryptedOut = ChainEncryptedOut(outputStream))
            using (Stream compressedOut = ChainCompressedOut(encryptedOut))
            {
                PgpSignatureGenerator signatureGenerator = InitSignatureGenerator compressedOut);
                using (Stream literalOut = ChainLiteralOut(compressedOut, unencryptedFileInfo))
                using (FileStream inputFile = unencryptedFileInfo.OpenRead())
                {
                    WriteOutputAndSign(compressedOut, literalOut, inputFile, signatureGenerator);
                }
            }
        }
    
        private static void WriteOutputAndSign(Stream compressedOut,Stream literalOut,FileStream inputFile,PgpSignatureGenerator signatureGenerator)
        {
            int length = 0;
            byte[] buf = new byte[BufferSize];
            while ((length = inputFile.Read(buf, 0, buf.Length)) > 0)
            {
                literalOut.Write(buf, 0, length);
                signatureGenerator.Update(buf, 0, length);
            }
            signatureGenerator.Generate().Encode(compressedOut);
        }
    
        private Stream ChainEncryptedOut(Stream outputStream)
        {
            PgpEncryptedDataGenerator encryptedDataGenerator;
            encryptedDataGenerator =
                new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes,
                                              new SecureRandom());
            encryptedDataGenerator.AddMethod(m_encryptionKeys.PublicKey);
            return encryptedDataGenerator.Open(outputStream, new byte[BufferSize]);
        }
    
        private static Stream ChainCompressedOut(Stream encryptedOut)
        {
            PgpCompressedDataGenerator compressedDataGenerator =
                new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
            return compressedDataGenerator.Open(encryptedOut);
        }
    
        private static Stream ChainLiteralOut(Stream compressedOut, FileInfo file)
        {
            PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
            return pgpLiteralDataGenerator.Open(compressedOut, PgpLiteralData.Binary, file);
        }
    
        private PgpSignatureGenerator InitSignatureGenerator(Stream compressedOut)
        {
            const bool IsCritical = false;
            const bool IsNested = false;
            PublicKeyAlgorithmTag tag = m_encryptionKeys.SecretKey.PublicKey.Algorithm;
            PgpSignatureGenerator pgpSignatureGenerator =
                new PgpSignatureGenerator(tag, HashAlgorithmTag.Sha1);
            pgpSignatureGenerator.InitSign(PgpSignature.BinaryDocument, m_encryptionKeys.PrivateKey);
    
            foreach (string userId in m_encryptionKeys.SecretKey.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator subPacketGenerator =
                   new PgpSignatureSubpacketGenerator();
                subPacketGenerator.SetSignerUserId(IsCritical, userId);
                pgpSignatureGenerator.SetHashedSubpackets(subPacketGenerator.Generate());
                // Just the first one!
                break;
            }
    
            pgpSignatureGenerator.GenerateOnePassVersion(IsNested).Encode(compressedOut);
            return pgpSignatureGenerator;
        }
    }
    

2 个答案:

答案 0 :(得分:0)

您应该获取邮件收件人的公钥,并生成您自己的密钥(如果您需要签名文件)。如果符合您的需要,PGP还允许基于密码的加密。 此外,我还建议您查看商业库(如SecureBlackbox)。它们很实用,但包括更好的支持,演示,文档等。

答案 1 :(得分:0)

我想你错过了一些代码?

 public class PgpEncryptionKeys {
    public PgpPublicKey PublicKey { get; private set; }
    public PgpPrivateKey PrivateKey { get; private set; }
    public PgpSecretKey SecretKey { get; private set; }
相关问题