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))));
        }