-1

我需要将 PGP 加密的 CSV 文件发送到 SFTP,但我对 PGP 一无所知。经过大量研究后,我可以使用 ' Bouncy Castle' Library在互联网上找到以下代码。该代码似乎是上帝,但鉴于我在 PGP 方面的经验不足,它对我不起作用。请帮助我找到正确的值:

  1. 公钥文件名
  2. 私有密钥文件名
  3. 密码短语

下面是我的代码:

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;
    }
}
4

2 回答 2

0

i think you miss some of the code?

 public class PgpEncryptionKeys {
    public PgpPublicKey PublicKey { get; private set; }
    public PgpPrivateKey PrivateKey { get; private set; }
    public PgpSecretKey SecretKey { get; private set; }
于 2013-07-03T19:35:59.907 回答
0

您应该获取消息接收者的公钥,并生成您自己的密钥(如果您需要签署文件)。如果这适合您的需要,PGP 还允许基于密码的加密。此外,我还建议您查看商业库(如 SecureBlackbox)。它们很昂贵,但包含更好的支持、演示、文档等。

于 2013-04-26T12:09:31.807 回答