Search code examples
c#cryptographyrsapgpopenpgp

How to encrypt for OpenPGP keys using C#?


I've been tasked with adding in a system that allows my company to encrypt files so that we can send them to a third party and they can run some operations on our data. The third party has given me a public key in this format,

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.18 (Darwin)

mQGiBFU1gfQRBACekfIt7mSynzBi0C2hIbvWM6mMh80ypw8NNvdCpOIfSwLVavej
YIESXe5yLGzWUoTnHALa5JHLJ2C3faeDHRBikXRESycRHz0itz3L/mlyIPLo7T1n
4zr2wUL+h0ZEmuhLeVBD+yLKzy68suEWXCcTkeh71vYG1r77RFJLtQHIfwCgu9DW
uJC8IHzXMrspotFIb0XF/VsD/iqdfRgdu7CkvUflwQsT66CmZcyfkkZkWpHXZoov
GP3ZCVKPfGEZqlThwuqgBCBbtsyZFSSmF8m5qjL/Dtz+t3/fxxTo1lXRr9P4f4Pl
n3OYQh+iOs1Z+7nnAZ4mulU1eRPYUY21e+UwKi+hd1Qe1ADOaH/9JVS8nrodePCO
qBFvBACXKEWpP937fZv1hGdqZ2OUM44RIf0PGbQwyG8a+DsksJgd0oY+sb5nTaB/
CgsEFgIDAQIeAQIXgAAKCRDEcHC8uF0CrVnTAJwLdvuBjv/Z8lySVZS7jInljU9y
sACdEtxmspV/GH7EDY0KtIydy3Vn8/eIXgQQEQgABgUCVTWCPAAKCRArjD/JWo9s
KvwNAP9CkZgMGn98wwMAixW5tIVA+J5kvdxnleg/wrR9xHsFYQD+KMraOkHSk10p
1EckgFK6LTuVqMvUoK9Gvr8v0rrHucW5Ag0EVTWB9BAIAP12dtlu0EuQ4s78ZWhM
cDJmpqot5FbMecPF20V5LsDFYbLGylEPPFFxNhwsc/l0Rlvg7auH2fcLSZf5hEp9
NsBhgWD532CAim9bFYF1s2bbjlZ7jUQD/Dt+9j1d9YrgCkF2/9er7RyfYwsRlVDQ
1nRCFLoQWLqisoILG65oloVtjNg6xftyLaLb6UuluW8dRM7q/9EvE0xPAX1ukc33
iGDWeMUR0JHyuM1QiN4IhOHKjP6Oqy+lJWtgoCQmxPJ2+Qj6b34wtsfD9vh3xLef
68ReXEOlfQ01tv6hQCrK/ZdvPLk38kVnwPOEJl/Hgj5eiVM3ioOlmBQoXKSpXyXI
wMKnovOEqJ2btp39XNpjjcV80RZiAJyAhNz2EynZk15QhOnabo9gdsiaMpBZdSdc
gDHowOXsWxzaVESs+SwJf/N2fa3j1UTDxCKkq5TOofvOfyPAYYASstmPw1v7xIcV
zn2nkKfBk1EnFM5PfwQAfXKUTx6BrZmITwQYEQgADwUCVTWB9AIbDAUJAsfqAAAK
CRDEcHC8uF0CrTI6AJ4oAZ2y4Pcahp+SRSNSW7Nijqdv2QCgnJ2EauQgU+rSyHyy
lkp3zJGdJTU=
=k/9l

-----END PGP PUBLIC KEY BLOCK-----

Can I stick this text string directly into say the RSACryptoServiceProvider class in C# as the public key? Or is there more to it than that? I haven't worked with PGP before, and I'm trying to know what I need to do in order to get data encrypted using this key.


Solution

  • Although OpenPGP takes advantage of RSA and other standard algorithms, you cannot use the default C# RSACryptoServiceProvider. RSA is only one possible algorithm for OpenPGP, and furthermore you need some symmetric encryption algorithm like AES (which would also be available). But there are further problems: you'd need to implement a generator for the OpenPGP message format, and OpenPGP defined its own cipher mode. Implementing all this on your own will not only be a hassle involving incompatibilities (an incomplete list exists in the RFC, but also has lots of ways to include security issues (and a bunch of further interesting attacks have been proposed and mitigated with existing implementations like GnuPG).

    If you want to use OpenPGP from C#, in the end it boils down to following alternatives:

    • use GnuPG through GPGME (but the wrapper still seems to be in alpha state),
    • use BouncyCastle which has native implementations of several cryptographic protocols including OpenPGP for both C# and Java, but the C#-implementation seems to be less wide-spread and is not as capable,
    • SharpPrivacy is another implementation, but seems dead
    • interface the GnuPG command line directly

    All of those have advantages and disadvantages. Probably BouncyCastle will be the best way to go, if it does not support the required features, you'll probably have to drop calling command GnuPG on the command line.