public void DKIMSign(ISigner signer, CanonicalizationType headerCanonicalization, CanonicalizationType bodyCanonicalization, HashingAlgorithm hashAlgorithm, string domain, string selector) { if (IsSigned) { throw new InvalidOperationException("Message already have DKIM header."); } IsSigned = true; string hashtype = hashAlgorithm == HashingAlgorithm.RSASha1 ? "sha1" : "sha256"; StringBuilder dkim = new StringBuilder(300) .Append("v=1;") // version .Append("a=").Append("rsa-").Append(hashtype).Append(";") // hash algorithm .Append("c=").Append(string.Format("{0}/{1}", headerCanonicalization, bodyCanonicalization).ToLower()).Append(";") // canonicalization types headers/body .Append("d=").Append(domain).Append(";") // domain for diim check .Append("s=").Append(selector).Append(";") // TXT record selector .Append("t=").Append(Convert.ToInt64((DateTime.Now.ToUniversalTime() - DateTime.SpecifyKind(DateTime.Parse("00:00:00 January 1, 1970"), DateTimeKind.Utc)).TotalSeconds).ToString()).Append(";") // creation time .Append("bh=").Append(GetBodyHash(bodyCanonicalization, hashtype)).Append(";"); // body hash var headers = ComputedHeaders; List <string> h = new List <string>(); foreach (string header in headers) { foreach (string value in headers.GetValues(header)) { h.Add(header); } } dkim.Append("h=").Append(string.Join(":", h)).Append(";") // headers for hashing .Append("b="); // signature data var canonialized = DKIMCanonicalizer.CanonicalizeHeader(headerCanonicalization, headers) + "dkim-signature:" + dkim.ToString(); var bytes = (HeadersEncoding ?? Encoding.UTF8).GetBytes(canonialized); lock (signer) { signer.BlockUpdate(bytes, 0, bytes.Length); bytes = signer.GenerateSignature();//computing signature signer.Reset(); } dkim.Append(Convert.ToBase64String(bytes)); Headers.Add("dkim-signature", dkim.ToString());// adding DKIM header }
public string GetBodyHash(CanonicalizationType type, string hashType) { var canonicalized = DKIMCanonicalizer.CanonicalizeBody(type, ComputedBody).TrimStart('\r', '\n'); return(Convert.ToBase64String(HashAlgorithm.Create(hashType).ComputeHash(Encoding.ASCII.GetBytes(canonicalized)))); }