【问题标题】:Redemption file saving using wrong encoding (maybe)使用错误编码保存赎回文件(可能)
【发布时间】:2020-04-06 12:48:06
【问题描述】:

我目前的项目是一个使用 Redemption 和 MimeKit 的电子邮件解密程序。这是一条漫长的道路,但在大多数情况下,它正在为我们的客户工作。

但是,对于一个外部公司的消息,生成的消息已损坏。输出消息成功保存到磁盘,当电子邮件在 Windows 资源管理器预览窗格中预览时,它呈现良好。但在 Outlook 中打开时,该消息似乎将扩展 ascii 字符转换为十六进制格式 (ISO-8859-1),即“ü”变为“=FC”。

这似乎适用于所有非标准 ascii 字符但仅来自一个特定的发件人(当前)

这些电子邮件可见的另一个问题是互联网标题在邮件中可见。 以下是解密电子邮件的(部分保护客户)屏幕截图:

需要注意的是,当解密的消息在 C# 中通过兑换重新加载时,HTMLBody 属性的格式似乎是正确的。

解密代码:

// "attach" object is the RDOAttachment (smime.p7m file)

DebugLog.Log($"Attachment Display name resembles that of an encrypted email");

// Is SMIME

byte[] decrypted;
DebugLog.Log($"Saving attach to disk");

attach.SaveAsFile(sourcePath + "-smime.p7m");
DebugLog.Log($"File exists: {File.Exists(sourcePath + "-smime.p7m").ToString()}");

MimeEntity entity = null;
DebugLog.Log($"MimeEntity: entity init");

MimeEntity finalOutput = null;
DebugLog.Log($"MimeEntity: finalOutput init");

using (MemoryStream ms = new MemoryStream())
//using (StreamWriter sw = new StreamWriter(ms))
using (FileStream file = new FileStream(sourcePath + "-smime.p7m", FileMode.Open, FileAccess.Read))
{
    DebugLog.Log($"Copying file to memory");

    file.CopyTo(ms);

    CryptographyContext.Register(typeof(WindowsSecureMimeContext));
    DebugLog.Log($"Registering CryptographicContext with typeof WindowsSecureMimeContext");

    ApplicationPkcs7Mime p7m = new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, ms);
    DebugLog.Log($"Creating new ApplicationPkcs7Mime object");

    var ctx = new WindowsSecureMimeContext(StoreLocation.CurrentUser);
    DebugLog.Log($"Printing available EncryptionAlgorithms");
    foreach (EncryptionAlgorithm alg in ctx.EnabledEncryptionAlgorithms)
    {
        DebugLog.Log($"Alg: {alg.ToString()}");
    }
    DebugLog.Log($"Setting context to CurrentUser");

    DebugLog.Log($"If p7m is not null and is envelope data");

    if (p7m != null && p7m.SecureMimeType == SecureMimeType.EnvelopedData)
    {
        try
        {
            //var y = p7m.Verify(ctx, out MimeEntity yeet);

            DebugLog.Log($"Attempting decrypt");

            entity = p7m.Decrypt(ctx);
        }
        catch (Exception e)
        {
            DebugLog.Log($"Error decrypting", e);
            DebugLog.Log($"Trying old method");
            try
            {
                using (var message = new MsgDecrypt.Message(sourcePath))
                {
                    message.SaveDecryptedCopyAs(destinationPath);
                    return;
                }
            }
            catch (Exception ex)
            {
                DebugLog.Log($"Error using old method:", ex);
                if (!(ex is CryptographicException))
                    throw ex;
            }

            if (!(e is CryptographicException))
                throw e;
            //throw e;
        }
    }
}

文件保存代码:

PrintObjectInfo(finalOutput);
DebugLog.Log(finalOutput.ContentType?.MimeType);
DebugLog.Log($"true");
try
{
    DebugLog.Log($"write to eml");
    using (FileStream fs = new FileStream(destinationPath + "-out.eml", FileMode.Create,
        FileAccess.ReadWrite))
    {
        finalOutput.WriteTo(fs);
    }

    DebugLog.Log($"success");

    Marshal.ReleaseComObject(attach);
    DebugLog.Log($"create empty message file ");

    var final = Session.CreateMessageFromMsgFile(destinationPath, "IPM.Note", msg.BodyFormat);

    final.Sent = true;
    //var x = File.ReadAllText("RTF.txt");

    final.Import(destinationPath + "-out.eml", rdoSaveAsType.olRFC822);

    if (final.Attachments.Count == 1)
    {
        if (final.Attachments.Item(1).DisplayName == "Untitled Attachment")
        {
            DebugLog.Log("Specific Attachment Delete Scenario has occured");
            final.Attachments.Clear();
        }
    }

    if (string.IsNullOrEmpty(final.HTMLBody) && !string.IsNullOrEmpty(final.RTFBody))
    {
        var x = final.RTFBody;
        final.RTFBody = x;
    }
    //final.HTMLBody = "";
    final.ReceivedByName = msg.ReceivedByName;

    final.Sender = msg.Sender;
    final.SenderEmailAddress = msg.SenderEmailAddress; // Fix empty name
    final.SenderName = msg.SenderName?.Replace("\"", "");

    final.Subject = msg.Subject;
    final.Recipients = msg.Recipients;
    final.SentOn = msg.SentOn;

    DebugLog.Log($"Save File");
    PrintObjectInfo(final);
    final.SaveAs(destinationPath, rdoSaveAsType.olMSGUnicode);

    var finalDis = final as IDisposable;
    finalDis.Dispose();
    try
    {
        var entDis = entity as IDisposable;
        entDis.Dispose();
    }
    catch (Exception)
    {

    }
    Marshal.ReleaseComObject(final);

    GC.Collect();
    GC.WaitForPendingFinalizers();
    File.Delete(destinationPath + "-out.eml");

    if (!File.Exists(destinationPath))
    {
        throw new Exception("File couln't be saved...");
    }
}
catch (Exception saveException)
{
    throw new Exception("Error saving new file", saveException);
}

如果您需要更多代码 sn-ps,请告诉我。

不幸的是,由于程序围绕着解密和人们的安全证书/凭证,调试这个问题是一个真正的痛苦。因此,解决此问题的任何帮助都将是巨大的帮助!

【问题讨论】:

  • 如何重现问题?您可以将原始 EML 文件和生成的 MSG 文件都压缩(重要!)并发送到 redemption (at) dimastr (dot) com 吗?
  • 再一次,在我所处的情况下,由于电子邮件已加密并且我无权访问用户的 SMIME 证书,因此无法访问。我有两封电子邮件(它们以 .msg 格式开头)我可以从解密的电子邮件中删除一些客户的信息并按照您的方式发送?
  • 让我们尝试获取 EML 文件 - 否则我们不知道问题出在 EML 文件中还是在将其导入到 MSG 文件中。

标签: c# encryption outlook outlook-redemption mimekit


【解决方案1】:

=FC-style 编码是在Content-Transfer-Encoding 标头中指定的quoted-printable 编码。

从您问题中提供的屏幕截图来看,text/plain 部分中的设置似乎正确。

也就是说,text/plain 部分的内容看起来像是被截断的开头(是否为了保护客户信息而进行了编辑?)而且它看起来也是 CSS/HTML 而不是纯文本。

【讨论】:

  • 这可能发生在 MimeKit 中解密后的步骤中吗?然后我将输出文件导入兑换。也是的,它被截断以保护信息
猜你喜欢
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
相关资源
最近更新 更多