例如一個URL如下http://xx.xx?key=value&key=value 現在要加上簽名驗證
建議加上時間戳參數防止一個接口在短時間內被多次請求
然后URL就變成了了http://xx.xx?key=value&key=value×tamp=時間戳
sign我這里用MD5加密
前端獲取sign方法
將要提交的參數提取出來將&符號去掉然后把參數排序,將排序后的參數拼接成一個字符串並且加上后端給的秘鑰,然后在使用MD5加密就生成了sign
然后URL就變成了了http://xx.xx?key=value&key=value×tamp=時間戳&sign=簽名
現在就可以提交了。
我們后端接請求后將所有參數放入一個字典,記得將sign參數移除,也可以在存放字典的時候就排除掉sign參數。
然后將字典的key排序,然后遍歷字典將參數拼接成一個字符串並在末尾加上秘鑰。
例如key1=value+key2=value+秘鑰 這里的時間戳也算key,value。
具體代碼如下
/// <summary>
/// 獲取簽名
/// </summary>
/// <param name="keyValues">URL參數</param>
/// <param name="secret">秘鑰</param>
/// <returns></returns>
public static string GetSign(Dictionary<string, string> keyValues, string secret)
{
keyValues.Remove("sign");
var orderkeyValues = keyValues.Keys.OrderBy(x => x);
StringBuilder builder = new StringBuilder();
foreach (var item in keyValues)
{
builder.Append($"{item.Key}={item.Value}");
}
builder.Append(secret);
var md5 = MD5.Create();
var bytes = Encoding.Default.GetBytes(builder.ToString());
var md5bytes = md5.ComputeHash(bytes);
return BitConverter.ToString(md5bytes).Replace("-","");
}
public static (bool,string) verifySign(Dictionary<string, string> keyValues)
{
var pasttime = System.Configuration.ConfigurationManager.AppSettings["pastdate"];
var secret = System.Configuration.ConfigurationManager.AppSettings["secret"];
var timestamp = keyValues["timestamp"];
var sign = keyValues["sign"];
if (timestamp != ""&& timestamp != null)
{
DateTime? date = webservice.timestamp.StampToDateTime(timestamp);
if (date is null) //時間轉換失敗
{
return (false, "時間戳轉換失敗");
}
else
{
DateTime time = DateTime.Now;
var pastdatetime = date?.AddMinutes(double.Parse(pasttime));
if (pastdatetime > time)
{
string gensign = GetSign(keyValues, secret);
if (gensign == sign)
{
return (true, "");
}
else
{
return (false, "簽名驗證失敗");
}
}
else
{ //簽名過期
return (false, "簽名過期");
}
}
}
return (false, "簽名驗證失敗");
}