RFC4871 – Section 3.7
The signer/verifier MUST compute two hashes, one over the body of
the message and one over the selected header fields of the message.
Signers MUST compute them in the order shown. Verifiers MAY compute
them in any order convenient to the verifier, provided that the
result is semantically identical to the semantics that would be the
case had they been computed in this order.
In hash step 1, the signer/verifier MUST hash the message body,
canonicalized using the body canonicalization algorithm specified in
the "c=" tag and then truncated to the length specified in the "l="
tag. That hash value is then converted to base64 form and inserted
into (signers) or compared to (verifiers) the "bh=" tag of the DKIM-
Signature header field.
------------------------------------------------------------------
MY INTERPRETATION
Take the message body:
1. Canonicalized using the body canonicalization algorithm specified
in the "c=" tag
2. Take the complete body (default value of "l-" tag)
3. Signer Hashes the canonicalized message body
4. Hash value is converted to Base64 form and inserted into signers
(???)
-------------------------------------------------------------------
In hash step 2, the signer/verifier MUST pass the following to the
hash algorithm in the indicated order.
1. The header fields specified by the "h=" tag, in the order
specified in that tag, and canonicalized using the header
canonicalization algorithm specified in the "c=" tag. Each header
field MUST be terminated with a single CRLF.
------------------------------------------------------------------
MY INTERPRETATION
Say by default we are signing the following header:
canonicalization (Date: xxx) <CRLF>
canonicalization (From: xxx) <CRLF>
canonicalization (To:xxxx) <CRLF>
canonicalization (Subject:xxxx) <CRLF>
------------------------------------------------------------------
2. The DKIM-Signature header field that exists (verifying) or
will be inserted (signing) in the message, with the value of
the "b=" tag deleted (i.e., treated as the empty string),
canonicalized using the header canonicalization algorithm specified
in the "c=" tag, and without a trailing CRLF.
-------------------------------------------------------------------
MY INTERPRETATION
Canoncalization (DKIM-Signature: v=1; a=rsa-sha256; d=infor.com;
s=rajtest; c=simple/simple; i=@*.infor.com; t=; x=; q=dns/txt;
h=Date:From:To:Subject; z=; bh=; b=)
-------------------------------------------------------------------
All tags and their values in the DKIM-Signature header field are
included in the cryptographic hash with the sole exception of the
value portion of the "b=" (signature) tag, which MUST be treated as
the null string. All tags MUST be included even if they might not
beunderstood by the verifier.
Include all tags in the DKIM-Signature header
Set the value of b to empty
The header field MUST be presented to the hash algorithm after the
body of the message rather than with the rest of the header fields
and MUST be canonicalized as specified in the "c="
(canonicalization) tag.
-------------------------------------------------------------------
I am not sure here specs are talking about DKIM-Signature field or
Header fields in general.
From Step 2: It looks like
canonicalization (Date: xxx) <CRLF>
canonicalization (From: xxx) <CRLF>
canonicalization (To: xxx) <CRLF>
canonicalization (Subject: xxx) <CRLF>
canonicalization (DKIM-Signature: xxx)
But the following phrase seems to be contradictory.
**** rather than with the rest of the header fields *****
------------------------------------------------------------------
The DKIM-Signature header field MUST NOT be included in its own h=
tag, although other DKIM-Signature header fields MAY be signed (see
Section 4).
******************************************************************
PSEUDO Algorithm
What I am planning to do:
1. Create a Signature Object [signature = Signature.getInstance
("SHA256withRSA");]
2. inputStreamBody = Canonicalized (body}
3. signature.update (input StreamBody)
4. inputStreamHeader = Canonicalized (date: xxx<CRLF>,from
xxx<CRLF>,to xxx<CRLF>, subject: xxx<CRLF>, dkim-signature}
5. signature.update (inputStreamHeader)
6. byte[] decoded = signature.sign();
7. Base64EncodedString = myBASE64Encoder(decoded);
8. DKIM-Signature: v=1; a=rsa-sha256; d=infor.com; s=rajtest;
c=simple/simple; i=@*.infor.com; t=; x=; q=dns/txt;
h=Date:From:To:Subject; z=; bh=; b= Base64EncodedString)
I am just wondering if my pseudo algorithm follows the specs or
there could be a better implementation.