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());
}