Search code examples
emailsha256dkim

How to validate DKIM body hash manually?


RFC5322 Procedure

This is an auto forwarded email. I'm trying to verify the bh field as per rfc5322. But the sha256 hash value received is not matching this value. The message body is: for forwarded mail Any suggestions to validate the bh= field correctly? I have included some sample header field data. Please do explain (relaxed) canonical procedure too

    DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1516798995;
        s=jan2017; d=headsup.co.in; i=sender@headsup.co.in;
        h=Date:From:To:Message-Id:Subject:MIME-Version:Content-Type; l=627;
        bh=ODw8icD/S+4UGcXgR4ocNpxXDh4PolWtd1IUXjh0AUs=;
        b=G2vTZ+uQ+krw49l+4aMnaeZjUvAJXPPRA8bvOhs3XZNbd2Ng+odB/F5PI3tRpdhr
        C0CJA5KPv4VncP2V1PjNdkgKLjs1eTzLSaqmPjhhQDc8mWQRT0rzcPP3V9v6BeXF987
        54Zns/QWtR+RbSacFXvUjyBEOlaWUVAmaVcqw5S8=

    //Message: for forwarded mail
  //Example Data
    Date: Wed, 24 Jan 2018 18:33:08 +0530
    From: sender <sender@headsup.co.in>
    To: "receiver" <receiver@gmail.com>
    Message-Id: <1612843d10d.d305604a24030.1212846966506749871@headsup.co.in>
    Subject: Test Arc Seal
    MIME-Version: 1.0
    Content-Type: multipart/alternative; 
        boundary="----=_Part_76205_1329960269.1516798988558"
    X-Priority: Medium  






//Cannonicalization code (relaxed)
package canonicalization;

import java.io.IOException;



public class Canonicalization {


        public String canonicalizeHeader(String name, String value) {
            name = name.trim().toLowerCase();
            value = value.replaceAll("\\s+", " ").trim();
            return name + ":" + value;
        }

        public String canonicalizeBody(String body) {

            if (body == null || "".equals(body)) {
                return "\r\n";
            }

            body = body.replaceAll("[ \\t\\x0B\\f]+", " ");
            body = body.replaceAll(" \r\n", "\r\n");

            // The body must end with \r\n
            if (!body.endsWith("\r\n")) {
                return body + "\r\n";
            }

            // Remove trailing empty lines ...
            while (body.endsWith("\r\n\r\n")) {
                body = body.substring(0, body.length() - 2);
            }

            return body;

        }
        public static void main(String[] args) {
            Canonicalization obj=new Canonicalization();
            System.out.println(obj.canonicalizeHeader("Date"," Wed, 24 Jan 2018 18:33:08 +0530"));
            System.out.println(obj.canonicalizeHeader("From"," sender <sender@headsup.co.in>"));
            System.out.println(obj.canonicalizeHeader("To"," \"receiver\" <receiver@gmail.com>"));

            System.out.println(obj.canonicalizeBody("for forwarded mail"));

        } 
}

Solution

  • The code works fine for emails sent in plaintext format (Content-Type: text/plain;)

    But by default, emails are sent by Rich Text Format (Content-Type: multipart/alternative;), hence the body hashes did not match