using System.Security.Cryptography; using System.Text; using System.Text.Json; namespace CampusErrand.Services; /// /// 腾讯 IM 服务,负责生成 UserSig /// public class TencentIMService { private readonly long _sdkAppId; private readonly string _secretKey; public TencentIMService(IConfiguration configuration) { var config = configuration.GetSection("TencentIM"); _sdkAppId = config.GetValue("SDKAppId"); _secretKey = config["SecretKey"]!; } public long SDKAppId => _sdkAppId; /// /// 生成 UserSig /// /// 用户标识 /// 有效期(秒),默认7天 public string GenerateUserSig(string userId, int expireSeconds = 604800) { var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var obj = new Dictionary { ["TLS.ver"] = "2.0", ["TLS.identifier"] = userId, ["TLS.sdkappid"] = _sdkAppId, ["TLS.expire"] = expireSeconds, ["TLS.time"] = now }; var contentToSign = $"TLS.identifier:{userId}\nTLS.sdkappid:{_sdkAppId}\nTLS.time:{now}\nTLS.expire:{expireSeconds}\n"; using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secretKey)); var sig = hmac.ComputeHash(Encoding.UTF8.GetBytes(contentToSign)); obj["TLS.sig"] = Convert.ToBase64String(sig); var jsonBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj)); // zlib 压缩 using var output = new MemoryStream(); using (var zlib = new System.IO.Compression.ZLibStream(output, System.IO.Compression.CompressionLevel.Optimal)) { zlib.Write(jsonBytes, 0, jsonBytes.Length); } // Base64 URL 安全编码 return Convert.ToBase64String(output.ToArray()) .Replace('+', '*') .Replace('/', '-') .Replace('=', '_'); } }