2013-04-26 78 views
0

我有一个要求将PGP加密的CSV文件发送到SFTP,我不知道什么是PGP。经过大量研究,我可以在互联网上使用'Bouncy Castle' Library找到以下代码。该代码似乎gogod,但由于我在PGP方面的经验不足而无法使用。请帮我在寻找正确的价值观:充气城堡加密

  1. publicKeyFileName
  2. privateKeyFileName
  3. pasPhrase

下面是我的代码:

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; 
    } 
} 
+0

IIRC您需要使用PGP工具为自己创建一个密钥。在那里你需要发明你自己的密码并获取这两个文件。 – 2013-04-26 12:02:34

+0

试过,发现密钥,但不知道如何利用密钥和publicKeyFileName,privateKeyFileName – 14578446 2013-04-26 12:05:24

回答

0

你应该得到接收者的公钥的消息,并生成您自己的密钥(如果您需要签署文件)。另外PGP允许基于密码的加密,如果这符合您的需求。 另外,我会建议看看商业图书馆(如SecureBlackbox)以及。他们是昂贵的,但包括更好的支持,演示,文档等。

+0

值是什么将是好的,我从一些网络生成器的密钥。但是我如何在这段代码中使用yhem? – 14578446 2013-04-26 12:18:14

+0

将它们存储到文件,并将publicKeyFileName设置为指向该文件。 – 2013-04-26 12:21:17

+0

在txt文件中?我做到了,但没有为我工作。 – 14578446 2013-04-26 12:24:13

0

我想你错过了一些代码?

public class PgpEncryptionKeys { 
    public PgpPublicKey PublicKey { get; private set; } 
    public PgpPrivateKey PrivateKey { get; private set; } 
    public PgpSecretKey SecretKey { get; private set; }