/// <summary> /// 对邮件内容进行签名,如果出错将返回错误 /// </summary> public Result <string> Sign(EMail_DKIM_RAW_EML eml) { var rtv = new Result <string>(); rtv.Value = ""; var body = eml.GetSignBody(true); var signHeadNames = eml.SelectSignHeaderNames(SignHeaderNames); var param = new List <string>(); param.Add("v=1"); param.Add("a=rsa-sha256"); param.Add("c=relaxed/relaxed"); param.Add("d=" + _EmailDomain); param.Add("s=" + _EmailSelector); param.Add("q=dns/txt"); param.Add("t=" + EMail_Unit.GetMS() / 1000); param.Add("h=" + signHeadNames.join(":")); param.Add("bh=" + Hash.SHA256.Base64(body)); param.Add("b="); var paramStr = param.join("; "); var signParams = eml.GetSignHeader(true, paramStr, null, signHeadNames); if (signParams.IsError) { signParams.errorTo(rtv); return(rtv); } rtv.Value = paramStr + _RSA.Sign("SHA256", signParams.Value); return(rtv); }
/// <summary> /// 验证邮件eml文件内容DKIM签名是否正确,没有签名或签名错误返回false /// </summary> public bool Verify(EMail_DKIM_RAW_EML eml) { if (eml == null) { return(false); } var sign = eml.GetHeader(DKIMKey); if (sign == null) { return(false); } var kvs = sign.split(";"); var kvDic = new Dictionary <string, string>(); var exp = new Regex(@"\s"); foreach (var kv in kvs) { var val = kv.splitTow("="); if (val[0] != "") { kvDic[exp.Replace(val[0], "")] = exp.Replace(val[1], ""); } } var hash256 = kvDic.getString("a") == "rsa-sha256"; Hash hash = hash256 ? Hash.SHA256 : Hash.SHA1; var cv = kvDic.getString("c").splitTow("/"); bool headRelaxed = true; bool bodyRelaxed = true; if (cv[1] == "") { headRelaxed = cv[0] == "relaxed"; bodyRelaxed = false; } else { headRelaxed = cv[0] == "relaxed"; bodyRelaxed = cv[1] == "relaxed"; } //验证body var body = eml.GetSignBody(bodyRelaxed); if (kvDic.getString("bh") != hash.Base64(body)) { return(false); } //验证head var heads = kvDic.getString("h").split(":"); var exp2 = new Regex(@"^([\S\s]+;\s+b=)([\S\s]+)$"); var m = exp2.Match(sign); if (!m.Success) { return(false); } var paramStr = m.Groups[1].Value; var signCode = exp.Replace(m.Groups[2].Value, ""); var signParams = eml.GetSignHeader(headRelaxed, paramStr, eml.GetHeaderMPKey(DKIMKey), heads); if (signParams.IsError) { return(false); } if (!_RSA.Verify(hash256 ? "SHA256" : "SHA1", signCode, signParams.Value)) { return(false); } return(true); }