75 lines
2.5 KiB
C#
75 lines
2.5 KiB
C#
using System.Security.Cryptography;
|
||
using System.Text;
|
||
|
||
namespace TrackCenter.Application.Helpers;
|
||
|
||
/// <summary>
|
||
/// API签名工具类
|
||
/// </summary>
|
||
public static class SignatureHelper
|
||
{
|
||
/// <summary>
|
||
/// 生成API签名
|
||
/// </summary>
|
||
/// <param name="appKey">应用唯一标识</param>
|
||
/// <param name="timestamp">时间戳(Unix时间戳,单位:秒)</param>
|
||
/// <param name="appSecret">应用密钥</param>
|
||
/// <returns>MD5签名结果(大写)</returns>
|
||
public static string GenerateSign(string appKey, long timestamp, string appSecret)
|
||
{
|
||
// 1. 排序后拼接:appKey, timestamp
|
||
var sortedParams = $"appKey={appKey}×tamp={timestamp}";
|
||
|
||
// 2. 拼接密钥:添加appSecret
|
||
var signString = $"{sortedParams}&appSecret={appSecret}";
|
||
|
||
// 3. 计算MD5并转大写
|
||
return CalculateMd5Hash(signString);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证签名
|
||
/// </summary>
|
||
/// <param name="appKey">应用唯一标识</param>
|
||
/// <param name="timestamp">时间戳</param>
|
||
/// <param name="sign">待验证的签名</param>
|
||
/// <param name="appSecret">应用密钥</param>
|
||
/// <param name="maxTimeDifferenceMinutes">允许的最大时间差(分钟),默认5分钟</param>
|
||
/// <returns>签名是否有效</returns>
|
||
public static bool VerifySign(string appKey, long timestamp, string sign, string appSecret, int maxTimeDifferenceMinutes = 5)
|
||
{
|
||
// 1. 验证时间戳(防止重放攻击)
|
||
var currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||
var timeDifference = Math.Abs(currentTimestamp - timestamp);
|
||
|
||
if (timeDifference > maxTimeDifferenceMinutes * 60)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// 2. 生成签名并比较
|
||
var expectedSign = GenerateSign(appKey, timestamp, appSecret);
|
||
return string.Equals(expectedSign, sign, StringComparison.OrdinalIgnoreCase);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算MD5哈希值(大写)
|
||
/// </summary>
|
||
/// <param name="input">输入字符串</param>
|
||
/// <returns>MD5哈希值(大写)</returns>
|
||
private static string CalculateMd5Hash(string input)
|
||
{
|
||
using var md5 = MD5.Create();
|
||
var inputBytes = Encoding.UTF8.GetBytes(input);
|
||
var hashBytes = md5.ComputeHash(inputBytes);
|
||
|
||
var sb = new StringBuilder();
|
||
foreach (var b in hashBytes)
|
||
{
|
||
sb.Append(b.ToString("X2"));
|
||
}
|
||
|
||
return sb.ToString();
|
||
}
|
||
}
|