c# - 使用错误编码保存赎回文件(可能)
问题描述
我目前的项目是一个使用 Redemption 和 MimeKit 的电子邮件解密程序。这是一条漫长的道路,但在大多数情况下,它正在为我们的客户服务。
但是,对于一个外部公司的消息,生成的消息已损坏。输出消息成功保存到磁盘,当电子邮件在 Windows 资源管理器预览窗格中预览时,它呈现良好。但在 Outlook 中打开时,该消息似乎将扩展 ascii 字符转换为十六进制格式 (ISO-8859-1),即“ü”变为“=FC”。
这似乎发生在所有非标准 ascii 字符上,但仅来自一个特定的发件人 only(current)。
这些电子邮件可见的另一个问题是互联网标题在邮件中可见。以下是解密电子邮件的(部分保护客户端)屏幕截图:
应该注意的是,当解密的消息通过兑换在 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);
}
如果您需要更多代码片段,请告诉我。
不幸的是,由于程序围绕着解密和人们的安全证书/凭证,调试这个问题是一个真正的痛苦。因此,解决此问题的任何帮助都将是巨大的帮助!
解决方案
=FC
-style 编码是quoted-printable
在标头中指定的编码Content-Transfer-Encoding
。
从您问题中提供的屏幕截图来看,它似乎在text/plain
部件中设置正确。
也就是说,该text/plain
部分的内容看起来像它的开头被截断(是否为保护客户信息而进行了编辑?)而且它看起来也是 CSS/HTML 而不是纯文本。
推荐阅读
- c - “错误:函数 'srand' 的隐式声明在 C99 中无效” 添加 stdlib.h 标头可消除此错误,但为什么呢?
- python - 谷歌云自然语言 Python“无法从 'google.cloud.language_v1' 导入名称'枚举'”
- git - GitHub中删除分支后如何在本地删除远程分支?
- javascript - Facebook 身份验证按钮无法在 Apify PuppeteerCrawler 生成的 Chromium 浏览器中加载
- elasticsearch - 将自动化 Postman 测试与弹性 apm 报告联系起来
- php - 使用 functions.php - 在 Woocommerce 中,我如何隐藏缺货的简单产品?
- r - 如何在R中转置部分数据帧?
- python - ValueError:检查目标时出错:预期activation_25 的形状为(1,),但得到的数组的形状为(4,)
- amazon-web-services - 基于 AWS API Gateway 控制器的动态重新路由
- haskell - 在 Xmonad 中为特定窗口配置无边框