Невозможно проверить хэш тела для DKIM

Я пишу валидатор C # DKIM и столкнулся с проблемой, которую не могу решить. Прямо сейчас я работаю над вычислением хэша тела, как описано в Раздел 3.7 Вычисление хэшей сообщений. Я работаю с электронными письмами, которые я сбросил, используя модифицированную версию образца EdgeTransportAsyncLogging в пакете SDK транспортного агента Exchange 2010. Вместо преобразования электронных писем при сохранении он просто открывает файл на основе MessageID и выгружает необработанные данные на диск.

Я могу успешно вычислить хэш тела образца электронного письма, представленного в Раздел A.2 с использованием следующего кода:

SHA256Managed hasher = new SHA256Managed();
ASCIIEncoding asciiEncoding = new ASCIIEncoding();
string rawFullMessage = File.ReadAllText(@"C:\Repositories\Sample-A.2.txt");
string headerDelimiter = "\r\n\r\n";
int headerEnd = rawFullMessage.IndexOf(headerDelimiter);
string header = rawFullMessage.Substring(0, headerEnd);
string body = rawFullMessage.Substring(headerEnd + headerDelimiter.Length);
byte[] bodyBytes = asciiEncoding.GetBytes(body);
byte[] bodyHash = hasher.ComputeHash(bodyBytes);
string bodyBase64 = Convert.ToBase64String(bodyHash);
string expectedBase64 = "2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=";
Console.WriteLine("Expected hash: {1}{0}Computed hash: {2}{0}Are equal: {3}",
  Environment.NewLine, expectedBase64, bodyBase64, expectedBase64 == bodyBase64);

Результатом приведенного выше кода является:

Expected hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Computed hash: 2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=
Are equal: True

Теперь большинство писем сталкиваются с настройкой c=relaxed/relaxed, которая требует, чтобы вы поработали над телом и заголовком перед хешированием и проверкой. И пока я работал над этим (не сумев заставить его работать), я, наконец, наткнулся на сообщение с c=simple/simple, что означает, что вы обрабатываете все тело, как и любые пустые CRLF в конце тела. (На самом деле правила канонизации тела довольно ... простой.)

Вот настоящая электронная почта DKIM (щелкните правой кнопкой мыши и сохраните, браузеры съедают окончание CRLF) с подписью по простому алгоритму (полностью без изменений). Теперь, используя приведенный выше код и обновляя хеш expectedBase64, я получаю следующие результаты:

Expected hash: VnGg12/s7xH3BraeN5LiiN+I2Ul/db5/jZYYgt4wEIw=
Computed hash: ISNNtgnFZxmW6iuey/3Qql5u6nflKPTke4sMXWMxNUw=
Are equal: False

Ожидаемый хэш - это значение из поля bh= заголовка DKIM-Signature. Теперь файл, используемый во втором тесте, представляет собой прямой необработанный выходной файл транспортного агента Exchange 2010. При желании вы можете просмотреть измененный EdgeTransportLogging.txt < / а>.

На этом этапе, независимо от того, как я изменяю второе электронное письмо, меняя начальную позицию или число CRLF в конце файла, я не могу добиться соответствия файлов. Что меня беспокоит, так это то, что я до сих пор не смог проверить какой-либо хэш тела (простой или упрощенный) и что обработка DKIM через Exchange 2010 может оказаться невозможной.


person Joshua    schedule 23.04.2010    source источник
comment
Решение есть на странице nicholas.piasecki.name/blog/2010/12/   -  person notandy    schedule 01.02.2012
comment
@notandy Спасибо, я больше не использую обмен, но моя проблема заключалась не в попытке подписать электронные письма (это было довольно просто), моя проблема заключалась в попытке проверить подпись DKIM во входящем сообщении. Насколько мне известно, это невозможно, поскольку нет способа заставить Exchange предоставить вам неизмененное тело для хеширования.   -  person Joshua    schedule 02.02.2012


Ответы (1)


Я пробовал это в python-dkim, и у меня тоже есть несоответствие хэша тела.

Я думаю, что, вероятно, Exchange _1 _ не дает вам фактических байтов в том виде, в каком они были переданы, поэтому хэш не совпадает. Вероятно, он разбирает сообщение на части mime, а затем GetMimeReadStream дает вам действительное представление сообщения, но не то, с которым оно было отправлено изначально.

Возможно, есть другой API, который даст вам настоящие необработанные байты?

Или, возможно, к этому моменту сообщение было разорвано, а исходное сообщение отброшено, и вам нужно подключиться раньше.

Вероятно, вам следует попробовать перехватить сообщение, подписанное DKIM, отправив его на сервер, не являющийся сервером Exchange, и посмотреть, работает ли это с вашим кодом. GetContentReadStream может сработать?

Как бы то ни было, что я сделал бы дальше, это попытался бы найти API, который бы побайтно передавал вам то, что было отправлено.

person poolie    schedule 01.06.2010
comment
Вы прибили его по голове. Насколько я могу судить, я получаю в основном пересобранное почтовое сообщение с достаточным количеством вариаций, чтобы оно не соответствовало должному. Хотя я не изучил все, похоже, что они не предоставляют способ захватить необработанные байты, поскольку они поступают, по крайней мере, не управляются. Похоже, что единственное решение (на данный момент) - это реализовать промежуточный SMTP-сервер (например, IIS), к которому вы можете подключиться и обработать его там. - person Joshua; 20.07.2010