127 lines
4.4 KiB
C#
127 lines
4.4 KiB
C#
|
|
using System;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Security.Cryptography;
|
|||
|
|
using System.Text;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
|
|||
|
|
namespace BLL
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// Token加密解密工具类
|
|||
|
|
/// 用于iframe跨域自动登录的token处理
|
|||
|
|
/// </summary>
|
|||
|
|
public static class TokenHelper
|
|||
|
|
{
|
|||
|
|
// 默认密钥,建议从配置文件中读取
|
|||
|
|
private static readonly string SecretKey = "cncec-subqhse-256bit-secret-key-for-auth-token";
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 加密Token
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="plainText">明文</param>
|
|||
|
|
/// <returns>加密后的Base64字符串</returns>
|
|||
|
|
public static string EncryptToken(string plainText)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 确保密钥长度为32字节(256位)
|
|||
|
|
string key = SecretKey.PadRight(32, '0').Substring(0, 32);
|
|||
|
|
|
|||
|
|
using (var aes = Aes.Create())
|
|||
|
|
{
|
|||
|
|
aes.Key = Encoding.UTF8.GetBytes(key);
|
|||
|
|
aes.IV = new byte[16]; // 使用固定IV,简化实现
|
|||
|
|
aes.Mode = CipherMode.CBC;
|
|||
|
|
aes.Padding = PaddingMode.PKCS7;
|
|||
|
|
|
|||
|
|
using (var encryptor = aes.CreateEncryptor())
|
|||
|
|
using (var msEncrypt = new MemoryStream())
|
|||
|
|
{
|
|||
|
|
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
|
|||
|
|
using (var swEncrypt = new StreamWriter(csEncrypt))
|
|||
|
|
{
|
|||
|
|
swEncrypt.Write(plainText);
|
|||
|
|
}
|
|||
|
|
return Convert.ToBase64String(msEncrypt.ToArray());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
throw new Exception($"Token加密失败: {ex.Message}", ex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 解密Token
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="cipherText">加密的Base64字符串</param>
|
|||
|
|
/// <returns>解密后的明文</returns>
|
|||
|
|
public static string DecryptToken(string cipherText)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 确保密钥长度为32字节(256位)
|
|||
|
|
string key = SecretKey.PadRight(32, '0').Substring(0, 32);
|
|||
|
|
|
|||
|
|
using (var aes = Aes.Create())
|
|||
|
|
{
|
|||
|
|
aes.Key = Encoding.UTF8.GetBytes(key);
|
|||
|
|
aes.IV = new byte[16]; // 使用固定IV,与加密一致
|
|||
|
|
aes.Mode = CipherMode.CBC;
|
|||
|
|
aes.Padding = PaddingMode.PKCS7;
|
|||
|
|
|
|||
|
|
using (var decryptor = aes.CreateDecryptor())
|
|||
|
|
using (var msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
|
|||
|
|
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
|||
|
|
using (var srDecrypt = new StreamReader(csDecrypt))
|
|||
|
|
{
|
|||
|
|
return srDecrypt.ReadToEnd();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
throw new Exception($"Token解密失败: {ex.Message}", ex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 生成认证Token
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="userId">用户ID</param>
|
|||
|
|
/// <param name="source">来源标识</param>
|
|||
|
|
/// <returns>加密的Token</returns>
|
|||
|
|
public static string GenerateAuthToken(string userId, string source = "qhse.cncecoa.com")
|
|||
|
|
{
|
|||
|
|
var tokenData = new
|
|||
|
|
{
|
|||
|
|
user_id = userId,
|
|||
|
|
timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
|||
|
|
source = source,
|
|||
|
|
random = Guid.NewGuid().ToString("N").Substring(0, 8) // 添加8位随机数增强安全性
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
string json = JsonConvert.SerializeObject(tokenData);
|
|||
|
|
return EncryptToken(json);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 验证Token格式
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="token">Token字符串</param>
|
|||
|
|
/// <returns>是否为有效的Base64格式</returns>
|
|||
|
|
public static bool IsValidTokenFormat(string token)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
Convert.FromBase64String(token);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
catch
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|