track/src/TrackCenter.Application/Helpers/SignatureHelper.cs
2025-11-29 17:23:19 +08:00

75 lines
2.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}&timestamp={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();
}
}