Search code examples
c#encryptionpublic-keypgppublic-key-encryption

C# How to simply encrypt a text file with a PGP Public Key?


I've researched a bit about how to achieve what I said in the question and found several APIs but most of them look very complicated and since I'm just a noobie in this area I just want a simple method like:

public String Encrypt(String message, PublicKey publicKey)

Don't know if this can be done? If not then please someone enlighten me another way to achieve this :)

Thank you.

UPDATE:

So far I have only seen that all of the library for OpenPGP encryption require both the public key and private key to do the encrypt while I only want to encrypt with the public key (because I don't have the private key to use it)!


Solution

  • I found a tutorial here but it requires both Secret Key and Public Key to encrypt data. However I've modified the codes a bit to only require public key (no signing, no compress) and thought I should publish it here in case anyone also looking for a solution for this question. Belows is the modified codes, all the credits for the author - Mr. Kim.

    public class PgpEncrypt
        {
            private PgpEncryptionKeys m_encryptionKeys;
            private const int BufferSize = 0x10000; 
            /// <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 Encrypt(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 literalOut = ChainLiteralOut(encryptedOut, unencryptedFileInfo))
                    using (FileStream inputFile = unencryptedFileInfo.OpenRead())
                    {
                        WriteOutput(literalOut, inputFile);
                    }
                }
            }
    
            private static void WriteOutput(Stream literalOut,
                FileStream inputFile)
            {
                int length = 0;
                byte[] buf = new byte[BufferSize];
                while ((length = inputFile.Read(buf, 0, buf.Length)) > 0)
                {
                    literalOut.Write(buf, 0, length);
                }
            }
    
            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 ChainLiteralOut(Stream encryptedOut, FileInfo file)
            {
                PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
                return pgpLiteralDataGenerator.Open(encryptedOut, PgpLiteralData.Binary, 
    
    file);
                } 
    }
    

    Of course to run these codes you have to include BouncyCastle library in your project.
    I've tested encrypting and then decrypting and it runs fine :)