0

我正在尝试处理签名和加密的电子邮件。更准确地说,我想下载一个附加的 Excel 文件。

据我目前所知,我拥有一个 pfx 文件(带有密码),它是一个包含用于解密的私钥和用于验证邮件发件人的证书(公钥)的存档。

编辑

在jstedfast的帮助下,我现在展示了一个最小的工作示例。

/* certificates */
X509Certificate2 certificate = new X509Certificate2(
    privateKeyFullFileName,
    privateKeyPassword,
    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Add(certificate);

/* smtp handling */
FindItemsResults<Item> inboxEMails = exchangeService.FindItems(WellKnownFolderName.Inbox, new ItemView(int.MaxValue));
EmailMessage eMail = // find appropriate mail
EmailMessage tmp = EmailMessage.Bind(ExchangeService, eMail.Id, new PropertySet(BasePropertySet.FirstClassProperties));
foreach (Attachment attachment in tmp.Attachments) {
  FileAttachment fa = attachment as FileAttachment;
  fa.Load();
  /* decrypting */
  using (MemoryStream rawStream = new MemoryStream(fa.Content)) {
    EnvelopedCms envelopedCms = new EnvelopedCms();
    envelopedCms.Decode(rawStream.ToArray());
    envelopedCms.Decrypt(collection); // <- decrypting with .pfx file
    using (MemoryStream decryptedStream = new MemoryStream(envelopedCms.ContentInfo.Content)) {
      MimeKit.MimeEntity entity = MimeKit.MimeEntity.Load(decryptedStream);
      if (entity is MimeKit.Cryptography.ApplicationPkcs7Mime) {
        MimeKit.Cryptography.ApplicationPkcs7Mime p7m = entity as MimeKit.Cryptography.ApplicationPkcs7Mime;
        using (MimeKit.Cryptography.TemporarySecureMimeContext ctx = new MimeKit.Cryptography.TemporarySecureMimeContext()) {
          Org.BouncyCastle.X509.X509Certificate cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
            ctx.Import(cert);
            if (p7m.SecureMimeType == MimeKit.Cryptography.SecureMimeType.SignedData) {
              MimeKit.MimeEntity extracted;
              MimeKit.Cryptography.DigitalSignatureCollection signatures = p7m.Verify(ctx, out extracted);
              MimeKit.MimePart part = extracted as MimeKit.MimePart;
              if (part != null) {
                // TODO
              }
              MimeKit.Multipart multipart = extracted as MimeKit.Multipart;
              if (multipart != null) {
                for (int i = 0; i < multipart.Count; ++i) {
                MimeKit.MimePart mimePart = multipart.ElementAt(i) as MimeKit.MimePart;
                if (mimePart != null && mimePart.IsAttachment) {
                  using (FileStream outStream = File.Create(/* path + */ mimePart.FileName)) {
                    try {
                      mimePart.Content.DecodeTo(outStream);
                    } catch { }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
4

1 回答 1

1

从 the 开始decryptedStream并假设它是一个application/pkcs7-mime; smime-type=signed-dataMIME 部分,您正确地开始了,但是您想要做的不是调用Import()而是调用Verify()

using (var decryptedStream = new MemoryStream (envelopedCms.ContentInfo.Content)) {
    var entity = MimeEntity.Load (decryptedStream);

    if (entity is ApplicationPkcs7Mime) {
        // Note: no need to create a new ApplicationPkcs7Mime part, just cast it!
        var p7m = (ApplicationPkcs7Mime) entity;
        using (var ctx = new TemporarySecureMimeContext ()) {
            // Import the X509Certificate2 into the S/MIME context
            var cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate (certificate);
            ctx.Import (cert);

            if (p7m.SecureMimeType == SecureMimeType.SignedData) {
                // Verify the content *and* extract the original content from the binary envelope
                MimeEntity extracted;

                var signatures = p7m.Verify (ctx, out extracted);

                // Save the Excel content to disk
                using (var stream = File.Create ("excel.xls")) {
                    var part = extracted as MimePart;

                    part.Content.DecodeTo (stream);
                }
            }
        }
    }
}
于 2018-03-26T20:42:13.097 回答