【问题标题】:Using GnuPG from C# (Mono) on Linux (Ubuntu)在 Linux (Ubuntu) 上使用 C# (Mono) 中的 GnuPG
【发布时间】:2013-11-15 08:29:16
【问题描述】:

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

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

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

【问题讨论】:

  • 您要执行哪种加密? .Net 和 mono 提供了 RSACryptoServiceProvider 和 DSACryptoServiceProvider 用于非对称加密,那么为什么要使用外部程序呢?
  • 有趣!但是 RSACryptoServiceProvider 可以使用 GnuPG 公钥文件 (.asc) 吗? GnuPG 电子邮件客户端是否能够解密使用 RSACryptoServiceProvider 加密的消息?
  • 我认为你不能直接使用 RSACryptoServiceProvider 使用 .asc 但我确信你可以将你的 .asc 文件转换为 xml,然后使用 xml 来创建 RSACryptoServiceProvider(参见 FromXmlString() 方法MSDN)。是的,您可以使用 RSACryptoServiceProvider 在一侧使用公钥加密消息,并在另一侧使用任何其他库或工具使用私钥对其进行解密。
  • 我的意思是双方当然必须使用RSA加密算法。还要记住,在 C# 中,所有字符串都以 Unicode 编码。所以如果要传输字符串,双方必须使用相同的char编码。

标签: c# linux encryption mono gnupg


【解决方案1】:

如果您想在 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# 中没有任何完整的绑定。我能找到的最好的是https://github.com/danm-de/gpgme-sharp,但它只适用于 32 位,而且现在很多系统都是 64 位的。

无论如何... MimeKit 可以进行 pgp 签名、验证、加密、解密、导入/导出密钥以及签名+加密和解密+验证等组合。此外,它还实现了所有 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 库可以提出 声明? :-)

【讨论】:

  • P.P.S.我是 Ubuntu 默认发布的邮件客户端的原始作者之一,我编写了它的 PGP/GnuPG 支持。这些天我在 Xamarin Inc 的 Mono 项目上工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
相关资源
最近更新 更多