質問

What I would like to do is to encrypt a string (E-Mail body) with a given public key (.asc file). Since I'm totally new to Linux I'm not sure how make use of an external process on that platform. The actual GnuPG command line syntax shouldn't be too hard I guess.

I've heard a lot about this "piping"-thing ;-) Can I do that from my C#-Application (e.g. via the Process class)? How does it work and what's the difference in doing the same thing on Windows?

And is there a way to do that cross-platform style so that my application will be able to invoke GnuPG on Linux AND Windows?

役に立ちましたか?

解決

If you want to do PGP email using Mono on Linux or any platform, really, I'd recommend looking at my MimeKit library at http://github.com/jstedfast/MimeKit

API documentation can be found at http://jstedfast.github.io/MimeKit/docs

All you need to do is subclass the MimeKit.Cryptography.GnuPGContext to override the abstract GetPassword() method and then call:

MimeKit.Cryptography.CryptographyContext.Register (typeof (MyGnuPGContext));

From then on, to encrypt a message, use MimeKit.Cryptography.MultipartEncrypted like so:

var message = new MimeMessage ();
// TODO: set the From, To, Subject, etc...

// create the message body
var body = new TextPart () { Text = "This is the message text..." };

// encrypt the body of the message
var encrypted = MultipartEncrypted.Create (message.To.Mailboxes, body);
message.Body = encrypted;

Now the body of your message is encrypted in the RFC-compliant way.

A few months ago, while writing my MimeKit library, I wanted to add PGP support (via GnuPG if I could) and the problem I had was that using System.Diagnostics.Process was just not flexible enough to invoke gpg in the ways I needed (in order to use gpg in a secure way, you need to open up several pipes to gpg so that you don't have to write the passphrase and other context to disk first). I've done this in C, but Process.Start(), for example, only allows me to manage stdin, stdout, and stderr, which just wasn't enough.

The GnuPG project has a library called libgpgme which is really great if you end up writing code in C, for example, but there aren't any complete bindings for it in C#. The best I could find was https://github.com/danm-de/gpgme-sharp but it only works for 32bit and many systems are 64bit these days.

Anyway... MimeKit can do pgp signing, verifying, encrypting, decrypting, importing/exporting keys, and combinations such as sign+encrypt and decrypt+verify. Plus it implements all of S/MIME (including stuff no other S/MIME library I could find supports, such as certs-only and compressed-data messages).

The README has instructions on how to build MimeKit (it's dead simple, but does require you to clone my bc-csharp github repository as well for all of the lower-level crypto logic).

Hope that helps.

P.S. I forgot to mention that MimeKit is completely cross-platform - it will work on Windows, Linux, and Mac. MimeKit itself (minus the crypto) will also work on iOS and Android. My goal for this weekend is to get the crypto stuff working on iOS and Android and making packages for that.

Now... MimeKit unfortunately doesn't have a compatible SmtpClient yet, but you could use MimeKit to do your PGP encryption and then extract the encrypted content for use inside System.Net.Mail like this:

// create a list of recipients
var recipients = new List<MailboxAddress> ();
recipients.Add (new MailboxAddress ("Joe Sixpack", "joe@sixpack.org"));

// create the message body
var body = new TextPart () { Text = "This is the message text..." };

// encrypt the body of the message
var multipart = MultipartEncrypted.Create (recipients, body);

// get the part that contains the ascii-armored pgp content
// (the second mime part of the multipart/encrypted)
var encrypted = (MimePart) multipart[1];

// get the ascii-armored encrypted content
var memory = new MemoryStream ();
encrypted.ContentObject.WriteTo (memory);
memory.Position = 0;

// at this point, 'memory' has the "--- BEGIN PGP MESSAGE ---" data
// and you can create your System.Net.Mail.MimeMessage and add a
// mime part with the memory stream as its content

I might look into seeing what it would involve to add a method or cast operator to convert a MimeKit.MimeMessage into a System.Net.Mail.MimeMessage, but I might not get around to it this weekend depending on how long it takes me to get the crypto stuff working on iOS and Android.

Update: I now have another library called MailKit that can be used for sending messages via SMTP. It also supports POP3 and IMAP.

I've also now finished porting MimeKit's crypto support over to iOS and Android... so MimeKit is now fully supported on Windows, Mac, Linux, iOS, and Android. How many other MIME libraries can make that claim? :-)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top