using System.Security.Cryptography;
using System.Text;
namespace TrackCenter.Application.Helpers;
///
/// API签名工具类
///
public static class SignatureHelper
{
///
/// 生成API签名
///
/// 应用唯一标识
/// 时间戳(Unix时间戳,单位:秒)
/// 应用密钥
/// MD5签名结果(大写)
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);
}
///
/// 验证签名
///
/// 应用唯一标识
/// 时间戳
/// 待验证的签名
/// 应用密钥
/// 允许的最大时间差(分钟),默认5分钟
/// 签名是否有效
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);
}
///
/// 计算MD5哈希值(大写)
///
/// 输入字符串
/// MD5哈希值(大写)
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();
}
}