1

我想做的是用给定的公钥(.asc 文件)加密字符串(电子邮件正文)。由于我对 Linux 完全陌生,我不确定如何在该平台上使用外部进程。我猜实际的 GnuPG 命令行语法应该不会太难。

我听说过很多关于这种“管道”的事情;-) 我可以从我的 C#-Application 中做到这一点(例如通过 Process 类)吗?它是如何工作的,在 Windows 上做同样的事情有什么区别?

有没有办法实现这种跨平台风格,以便我的应用程序能够在 Linux 和 Windows 上调用 GnuPG?

4

1 回答 1

4

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? :-)

于 2013-11-16T02:21:41.163 回答