PGP encryption in c# .net

Posted by Andrew Denner on April 26, 2022 · 2 mins read

A while back I needed to do public/private encryption in c#. My goto (if it isn’t in the core library) for encryption in C# and java is bouncycastle. However, with that being said, it is not the easiest to use. (and as a developer I am lazy.)

The good news, as with most itches, someone has already scratched it. (don’t kink shame me…) In this case, there is a lovely (if slightly limited) wrapper called ChoPGP (for modern .net core you will want ChoPGP.Core) that under the hood is using a .net branch of bouncy castle.

To install it in your solution, run the command dotnet add ChoPGP.Core

From there, to create your public/private keys:

        public static (string pub, string pri) CreateKey()
        {
            using (ChoPGPEncryptDecrypt pgp = new ChoPGPEncryptDecrypt())
            using (MemoryStream pubkey = new MemoryStream(), prikey = new MemoryStream())
            {
                pgp.CompressionAlgorithm = ChoCompressionAlgorithm.BZip2;
                pgp.GenerateKey(pubkey, prikey, null, null, 2048, 16, true);
                var pubstring = Encoding.UTF8.GetString(pubkey.ToArray());
                var pristring = Encoding.UTF8.GetString(prikey.ToArray());
                return (pubstring, pristring);
            }

        }

and to encrypt (where pl is your string payload, and k is your public key)

            using (ChoPGPEncryptDecrypt pgp = new ChoPGPEncryptDecrypt())
            using (MemoryStream key = new MemoryStream(Encoding.UTF8.GetBytes(k)), payload = new MemoryStream(Encoding.UTF8.GetBytes(pl)), os = new MemoryStream())
            {
                pgp.CompressionAlgorithm = ChoCompressionAlgorithm.BZip2;
                pgp.Encrypt(payload, os, key, true, true);
                return Encoding.UTF8.GetString(os.ToArray());
            }

Finally, to decode (where k is your private key, and pl is the encrypted message):

            using (ChoPGPEncryptDecrypt pgp = new ChoPGPEncryptDecrypt())
            using (MemoryStream key = new MemoryStream(Encoding.UTF8.GetBytes(k)), payload = new MemoryStream(Encoding.UTF8.GetBytes(pl)), os = new MemoryStream())
            {
                pgp.CompressionAlgorithm = ChoCompressionAlgorithm.BZip2;
                pgp.Decrypt(payload, os, key,null);
                return Encoding.UTF8.GetString(os.ToArray());
            }