c# - 在 Linux (Ubuntu) 上从 C# (Mono) 使用 GnuPG

标签 c# linux encryption mono gnupg

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

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

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

最佳答案

如果您想在 Linux 或任何平台上使用 Mono 处理 PGP 电子邮件,真的,我建议您查看我的 MimeKit 库 http://github.com/jstedfast/MimeKit

API 文档可以在 http://jstedfast.github.io/MimeKit/docs 找到

您需要做的就是继承 MimeKit.Cryptography.GnuPGContext 以覆盖抽象的 GetPassword() 方法,然后调用:

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

从那时起,要加密消息,请像这样使用 MimeKit.Cryptography.MultipartEncrypted:

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;

现在您的消息正文以符合 RFC 的方式加密。

几个月前,在编写我的 MimeKit 库时,我想添加 PGP 支持(如果可以的话,通过 GnuPG),我遇到的问题是使用 System.Diagnostics.Process 不够灵活,无法在我需要的方式(为了以安全的方式使用 gpg,您需要打开几个到 gpg 的管道,这样您就不必先将密码和其他上下文写入磁盘)。我在 C 中完成了此操作,但是 Process.Start() 仅允许我管理 stdin、stdout 和 stderr,这还不够。

GnuPG 项目有一个名为 libgpgme 的库,例如,如果您最终用 C 编写代码,它真的很棒,但在 C# 中没有任何完整的绑定(bind)。我能找到的最好的是 https://github.com/danm-de/gpgme-sharp但它仅适用于 32 位,而如今许多系统都是 64 位的。

无论如何... MimeKit 可以进行 pgp 签名、验证、加密、解密、导入/导出 key ,以及签名+加密和解密+验证等组合。此外,它实现了所有 S/MIME(包括我找不到其他 S/MIME 库支持的东西,例如仅证书和压缩数据消息)。

自述文件包含有关如何构建 MimeKit 的说明(非常简单,但确实需要您克隆我的 bc-csharp github 存储库以及所有较低级别的加密逻辑)。

希望对您有所帮助。

附言我忘了说 MimeKit 是完全跨平台的——它可以在 Windows、Linux 和 Mac 上运行。 MimeKit 本身(减去加密)也可以在 iOS 和 Android 上运行。我这个周末的目标是让加密的东西在 iOS 和 Android 上运行并为此制作包。

现在...不幸的是,MimeKit 还没有兼容的 SmtpClient,但您可以使用 MimeKit 进行 PGP 加密,然后提取加密内容以在 System.Net.Mail 中使用,如下所示:

// 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

我可能会研究添加方法或转换运算符以将 MimeKit.MimeMessage 转换为 System.Net.Mail.MimeMessage 会涉及什么,但我可能不会在这个周末抽出时间来解决它,具体取决于它需要多长时间带我了解在 iOS 和 Android 上运行的加密技术。

更新:我现在有另一个库叫做 MailKit可用于通过 SMTP 发送消息。它还支持 POP3 和 IMAP。

我现在还完成了将 MimeKit 的加密支持移植到 iOS 和 Android 的工作...因此 MimeKit 现在在 Windows、Mac、Linux、iOS 和 Android 上得到了完全支持。有多少其他 MIME 库可以那个声明? :-)

关于c# - 在 Linux (Ubuntu) 上从 C# (Mono) 使用 GnuPG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19996637/

相关文章:

c# - 将值标准化为 -1 到 1 之间的范围

ios - 用于访问远程服务器上的照片或图片的任何现有协议(protocol)

javascript - 使用 node-jose,如何解密刚刚加密的数据?

ssl - 从 RSA key 生成 PKCS#12 key 的问题

c# - CheckedListBox 中的第二级

c# - 回发发生在 asp.net 中丢失的 javascript 列表框项目

c# - WCF 服务。如何返回 HTTP 500 响应

linux - 在 git bash 中设置斜杠目录

linux - 如何限制用户访问主文件夹

java - Hibernate - 将列存储为加密,并仅在运行时解密