加密方法有很多,以下是其中一种简单的签名模式
1、首先客户端通过webapi按照IP地址,时间戳,随机数生成签名,并传递序列号
private Result_Sign Valid() { string ServerIP = "192.168.1.6";// HttpContext.Request.ServerVariables.Get("Local_Addr").ToString(); //地址 string timestamp = DateTimeToStamp(DateTime.Now); //时间戳
string nonce = ST.WEB.App_Start.Common.CreateValidateCode(6);//随机数 string SignStr = SignatureString(ServerIP, timestamp, nonce);//生成签名 string appseq = ConfigurationManager.AppSettings["DPSeq"]; //产品序列号 string Url = string.Format("http://www.abc.com:89/api/Valid?signature={0}×tamp={1}&nonce={2}&appseq={3}", SignStr, timestamp, nonce, appseq);//POST发送URL string resStr = ST.WEB.App_Start.Common.Get_Http(Url, 12000); Result_Sign resJson = new Result_Sign() { code = "-1", message = "" }; if (resStr.Substring(0, 2) != "错误") { resJson = JsonConvert.DeserializeObject<Result_Sign>(resStr); } return resJson; }
// DateTime时间格式转换为Unix时间戳格式 private string DateTimeToStamp(DateTime time) { System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); return ((int)(time - startTime).TotalSeconds).ToString(); }
//生成签名串
private string SignatureString(string appIP, string timestamp, string nonce) { string[] ArrTmp = { appIP, timestamp, nonce }; Array.Sort(ArrTmp); string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); return tmpStr.ToLower(); }
//生成随机数
public static string CreateValidateCode(int length){ int[] randMembers = new int[length]; int[] validateNums = new int[length]; string validateNumberStr = ""; //生成起始序列值 int seekSeek = unchecked((int)DateTime.Now.Ticks); Random seekRand = new Random(seekSeek); int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000); int[] seeks = new int[length]; for (int i = 0; i < length; i++) { beginSeek += 10000; seeks[i] = beginSeek; } //生成随机数字 for (int i = 0; i < length; i++) { Random rand = new Random(seeks[i]); int pownum = 1 * (int)Math.Pow(10, length); randMembers[i] = rand.Next(pownum, Int32.MaxValue); } //抽取随机数字 for (int i = 0; i < length; i++) { string numStr = randMembers[i].ToString(); int numLength = numStr.Length; Random rand = new Random(); int numPosition = rand.Next(0, numLength - 1); validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1)); } for (int i = 0; i < length; i++) { validateNumberStr += validateNums[i].ToString(); } return validateNumberStr; }
/// <summary> /// 获取远程服务器ATN结果 /// </summary> /// <param name="strUrl">指定URL路径地址</param> /// <param name="timeout">超时时间设置</param> /// <returns>服务器ATN结果</returns> public static string Get_Http(string strUrl, int timeout) { string strResult; try { HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl); myReq.Timeout = timeout; HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse(); Stream myStream = HttpWResp.GetResponseStream(); StreamReader sr = new StreamReader(myStream, Encoding.Default); StringBuilder strBuilder = new StringBuilder(); while (-1 != sr.Peek()) { strBuilder.Append(sr.ReadLine()); } strResult = strBuilder.ToString(); } catch (Exception exp) { strResult = "错误:" + exp.Message; } return strResult; }2、服务器端获取数据并验证返回结果
[HttpGet] public Result_Sign Sign(string signature, string timestamp, string nonce, string appseq) { Result_Sign sign = new Result_Sign() { code="0", message="fault" }; if (Tool.ValidateSignature(signature, timestamp, nonce, appseq)) { sign.code = "1"; sign.message = "success"; } return sign;
}
/// <summary> /// 检查应用接入的数据完整性 /// </summary> /// <param name="signature">加密签名内容</param> /// <param name="timestamp">时间戳</param> /// <param name="nonce">随机字符串</param> /// <param name="appseq">序列号</param> /// <returns></returns> public static bool ValidateSignature(string signature, string timestamp, string nonce, string appseq) { bool result = false; Register item = Cache.GetBySeq(appseq);//获取序列号相关信息 if (item != null) { if (DateTime.Parse(item.ExpireDT) < DateTime.Now.Date) //是否过期 { return result; } #region 校验签名参数的来源是否正确 string[] ArrTmp = { item.IP, timestamp, nonce }; Array.Sort(ArrTmp); string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); tmpStr = tmpStr.ToLower(); if (tmpStr == signature && isNumberic(timestamp)) { //验证成功 DateTime dtTime = StampToDateTime(timestamp); double minutes = DateTime.Now.Subtract(dtTime).TotalMinutes; if (minutes < 5) //时间不能大于5分钟 { result = true; } } #endregion } return result;}
/// <summary> /// 时间戳转时间 /// </summary>/// <param name="timeStamp"></param>/// <returns></returns> private static DateTime StampToDateTime(string timeStamp) { DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); long lTime = long.Parse(timeStamp + "0000000"); TimeSpan toNow = new TimeSpan(lTime); return dateTimeStart.Add(toNow); }
/// <summary>/// 是否为数字 /// </summary> /// <param name="message"></param> /// <returns></returns> protected static bool isNumberic(string message) { System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"^\d+$"); if (rex.IsMatch(message)) { return true; } else return false; }
public class Result_Sign{ public string code { set; get; } public string message { set; get; }}