Сохранение файла выкупа с использованием неправильной кодировки (возможно) - PullRequest
1 голос
/ 06 апреля 2020

Мой текущий проект - программа расшифровки электронной почты, использующая Redemption и MimeKit. Это был долгий путь, но по большей части он работает для нашего клиента.

Однако для сообщений одной внешней компании результирующее сообщение повреждено. Выходное сообщение успешно сохраняется на диск, при предварительном просмотре электронной почты в Windows области просмотра Explorers оно отображается хорошо. Но при открытии в outlook сообщение, похоже, преобразует символы расширенной ascii в шестнадцатеричный формат (ISO-8859-1), т. Е. "Ü" становится "= F C".

Это, кажется, происходит для всех нестандартные символы ascii Но только из одного указанного c отправителя (в настоящее время) .

Другая проблема, которая видна в этих письмах, заключается в том, что заголовки inte rnet видны на сообщение. Ниже приведен снимок экрана ( Частично для защиты клиента ) расшифрованного электронного письма:

Screenshot of decrypted email saved with Redemption

Следует отметить, что при расшифрованное сообщение повторно загружено в 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);
}

Если вам больше нужны фрагменты кода, пожалуйста, дайте мне знать.

К сожалению, поскольку программа вращается вокруг дешифрования и защищенных сертификатов / учетных данных пользователей, отладка этой проблемы реальная боль. Поэтому любая помощь в решении этой проблемы будет огромной помощью!

1 Ответ

0 голосов
/ 07 апреля 2020
Кодировка

=FC - это кодировка quoted-printable, указанная в заголовке Content-Transfer-Encoding.

На скриншоте, представленном в вашем вопросе, похоже, что он правильно установлен в text/plain part.

Тем не менее, содержимое text/plain части выглядит так, будто ее начало усечено (было ли это отредактировано для защиты информации о клиенте?), а также выглядит как CSS / HTML, а не как простой текст.

...