-1

I have a requirment to send PGP Encrypted CSV Files to SFTP and i know nothing aboutr PGP. After a lot of research I could find following code on internet using 'Bouncy Castle' Library. The code seems gogod but does not work for me given my inexperience in PGP. Please help me in finding right values for:

  1. publicKeyFileName
  2. privateKeyFileName
  3. pasPhrase

Below is my code:

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;
    }
}
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
14578446
  • 1,044
  • 7
  • 30
  • 50
  • IIRC you need to create a key for yourself, using the PGP tools. There you will need to invent your own passphrase and get both files. – Hans Kesting Apr 26 '13 at 12:02
  • tried that and found keys but dont know how to utilize the keys and what will be the values for publicKeyFileName, privateKeyFileName – 14578446 Apr 26 '13 at 12:05

2 Answers2

0

You should obtain public key of the recipient of the message, and generate your own secret key (if you need to sign files). Also PGP allows password-based encryption, if this suits your needs. Also I would recommend to take a look on commercial libraries (like SecureBlackbox) as well. They are costy, but includes much better support, demos, documentation, etc.

Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48
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; }
Waleed A.K.
  • 1,596
  • 13
  • 13