/// <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> /// 获取邮件的内容 /// </summary> public static Result <EMail_DKIM_RAW_EML> ToRAW(MailMessage message) { var rtv = new Result <EMail_DKIM_RAW_EML>(); if (MailWriterFactory == null || Close == null || Send2 == null && Send3 == null) { rtv.error("email内容获取器未初始化成功"); return(rtv); } var headers = message.Headers; //备份hook head var hT = headers[EMail_DKIM.DKIMTimeKeyT]; var hTS = headers[EMail_DKIM.DKIMTimeKeyTS]; try { using (var internalStream = new ClosableMemoryStream()) { object mailWriter = MailWriterFactory(internalStream); if (Send2 != null) { Send2(message, mailWriter, false); } else if (Send3 != null) { //由smtp.DeliveryFormat决定的allowUnicode为false Send3(message, mailWriter, false, false); } Close(mailWriter); internalStream.Position = 0; string text; using (var reader = new StreamReader(internalStream, Encoding.UTF8)) { text = reader.ReadToEnd(); } internalStream.ReallyClose(); var val = EMail_DKIM_RAW_EML.ParseOrNull(text); if (val == null) { rtv.error("整个email内容获取后解析失败"); return(rtv); } rtv.Value = val; return(rtv); } } catch (Exception e) { rtv.fail("无法获取整个email内容:" + e.Message, e.ToString()); return(rtv); } finally { //还原hook head if (hTS != null) { headers.Set(EMail_DKIM.DKIMTimeKeyT, hT); headers.Set(EMail_DKIM.DKIMTimeKeyTS, hTS); } } }
/// <summary> /// 获取邮件的内容 /// </summary> public static Result <EMail_DKIM_RAW_EML> ToRAW(MailMessage message) { var rtv = new Result <EMail_DKIM_RAW_EML>(); if (MailWriterFactory == null || Close == null || Send2 == null && Send3 == null) { rtv.error("email内容获取器未初始化成功"); return(rtv); } try { using (var internalStream = new ClosableMemoryStream()) { object mailWriter = MailWriterFactory(internalStream); if (Send2 != null) { Send2(message, mailWriter, false); } else if (Send3 != null) { Send3(message, mailWriter, false, false); } Close(mailWriter); internalStream.Position = 0; string text; using (var reader = new StreamReader(internalStream, Encoding.UTF8)) { text = reader.ReadToEnd(); } internalStream.ReallyClose(); var val = EMail_DKIM_RAW_EML.ParseOrNull(text); if (val == null) { rtv.error("整个email内容获取后解析失败"); return(rtv); } rtv.Value = val; return(rtv); } } catch (Exception e) { rtv.fail("无法获取整个email内容:" + e.Message, e.ToString()); 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); }
/// <summary> /// 验证邮件eml文件内容DKIM签名是否正确,没有签名或签名错误返回false /// </summary> public bool Verify(string eml) { return(Verify(EMail_DKIM_RAW_EML.ParseOrNull(eml))); }