LASAPlatform/Infrastructure/Helpers/EncryptionHelper.cs

225 lines
7.7 KiB
C#
Raw Normal View History

2025-07-02 09:35:20 +08:00
using NPOI.POIFS.Crypt.Dsig;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
2025-07-02 09:35:20 +08:00
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
2025-07-02 09:35:20 +08:00
using System;
using System.Buffers.Text;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive;
2025-07-02 09:35:20 +08:00
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Unicode;
using System.Threading.Tasks;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Asn1;
2025-07-02 09:35:20 +08:00
namespace Infrastructure.Helpers
{
2026-02-04 08:38:14 +08:00
public class EncryptionHelper
2025-07-02 09:35:20 +08:00
{
2026-02-04 08:38:14 +08:00
//String privateKey = "ABA4354EFAFE944C2F226A3981C7DC70F43BD6053EDA83F4DC274242BBB23CAA";
String privateKey = "32E324B2FBA5A6CF0D4645EE2D6B3295A6D9D3682C172B2D32E95EDD04340EF1";
//String publicKey = "04F1BF1BEFD63F16E5DB3BCD32CA5D9A8E8DF7ADD67D6C4F293FB23F7BDA74F52D31B8DDAD03D955D566505A15D8B7DBE83B42378B8E8749C0EB6E2FBC8675838B";
//string publickey = "04D6974E2384ECE39F5ADF1473E4B9B60E0D438A6F701F667C0C88D25BE2F8508A3AAFF9D9500ECFFD8E79B2DE58C024B689B5C207486646EA08A352FBB0016D46";
//string publickey = "04CF7CAE31B5130D1D5D1AC1DC2778D94533868A8D57FC02BBD97B688E07145DAAA96462DC83D9F348261F738D51C049770C43BA53B584917C9E30C6221B737CDD";
string publickey = "04D9D42CFD9633871B5540A4C891A6230A872EBB661FD2537C19817052728143AF53FEF4B38FCF8C2395C237308B7B8C21D93E94FE34E826220580D7BAFCD5F04B";
2025-07-02 09:35:20 +08:00
byte[] sm4Key = null;
public EncryptionHelper()
{
}
/// <summary>
/// 获取x-lc-secret
/// </summary>
/// <returns></returns>
public string getxseret()
{
if (sm4Key == null)
{
sm4Key = SM4CryptoHelper.GenerateSM4Key();
}
//十六进制字符串 → 字节数组 publickey
2025-07-07 13:59:05 +08:00
byte[] publickeybyte = HexToBytes(publickey);
2025-07-02 09:35:20 +08:00
var encryptdatasm2 = SM2CryptoHelper.Encrypt(publickeybyte, sm4Key);
return Convert.ToBase64String(encryptdatasm2);
}
/// <summary>
/// 数据加密
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string Encrypt(byte[] input)
{
if (sm4Key == null)
{
sm4Key = SM4CryptoHelper.GenerateSM4Key();
}
var encryptdatasm4 = SM4CryptoHelper.Encrypt(sm4Key, input);
return Convert.ToBase64String(encryptdatasm4);
}
/// <summary>
/// 数据解密
/// </summary>
/// <param name="x_lc_screte"></param>
/// <param name="output"></param>
/// <returns></returns>
2026-02-04 08:38:14 +08:00
public string Decrypt(byte[] x_lc_screte, byte[] output)
2025-07-02 09:35:20 +08:00
{
byte[] privatekeybyte = HexToBytes(privateKey);
byte[] sm4key = SM2CryptoHelper.Decrypt(privatekeybyte, x_lc_screte);
var decryptdata = SM4CryptoHelper.Decrypt(sm4key, output);
return Encoding.UTF8.GetString(decryptdata);
}
/// <summary>
/// 获取x-lc-token
/// </summary>
/// <param name="certCode"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public string GetToken(string certCode)
{
// 获取毫秒级时间戳(.NET 中 Ticks 转换为毫秒)
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
//long timestamp = 1751274197662;
// 拼接待签名数据
string needSignData = certCode + timestamp;
byte[] needSignDataByte = Encoding.UTF8.GetBytes(needSignData);
// 4. SM2签名
byte[] signData;
byte[] privatekeybyte = HexToBytes(privateKey);
try
{
signData = SM2CryptoHelper.Sign(privatekeybyte, needSignDataByte);
}
catch (Exception ex)
{
throw new InvalidOperationException("SM2签名失败", ex);
}
// Base64 编码签名(直接使用 Convert
string signDataBase64 = Convert.ToBase64String(signData);
// 生成 token
string token = $"{certCode}.{timestamp}.{signDataBase64}";
return token;
}
public bool Verify(string str)
{
string signData = "";
// 拼接待签名数据
string needSignData = "";
2026-02-04 08:38:14 +08:00
if (!string.IsNullOrEmpty(str))
{
2026-02-04 08:38:14 +08:00
string[] tokenstr = str.Split(".");
signData = tokenstr[2];
needSignData = tokenstr[0] + tokenstr[1];
}
2026-02-04 08:38:14 +08:00
byte[] signbyte = Convert.FromBase64String(signData);
byte[] needSignDataByte = Encoding.UTF8.GetBytes(needSignData);
// 4. SM2验签 publickey
2025-07-07 13:59:05 +08:00
byte[] publickeybyte = HexToBytes(publickey);
try
{
return SM2CryptoHelper.Verify(publickeybyte, needSignDataByte, signbyte);
}
catch (Exception ex)
{
throw new InvalidOperationException("SM2签名失败", ex);
}
}
2025-07-02 09:35:20 +08:00
/// <summary>
/// 内部转byte方法
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public static byte[] HexToBytes(string hex)
{
if (hex == null)
throw new ArgumentNullException(nameof(hex));
if (hex.Length % 2 != 0)
throw new ArgumentException("十六进制字符串长度必须是偶数");
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
string byteStr = hex.Substring(i * 2, 2);
bytes[i] = Convert.ToByte(byteStr, 16);
}
return bytes;
}
#region 图片上传校验码生成
public string GetJYM(string str)
{
string sm3str = ComputeSm3Hash(str);
//return GenerateSm2Signature(sm3str);
byte[] needSignDataByte = Encoding.UTF8.GetBytes(sm3str);
// 4. SM2签名
byte[] signData;
byte[] privatekeybyte = HexToBytes(privateKey);
try
{
signData = SM2CryptoHelper.Sign(privatekeybyte, needSignDataByte);
// 将签名结果转换为十六进制大写字符串
string hexSignature = BytesToHexUpper(signData);
return hexSignature;
}
catch (Exception ex)
{
throw new InvalidOperationException("SM2签名失败", ex);
}
}
// 将字节数组转换为十六进制大写字符串
private static string BytesToHexUpper(byte[] bytes)
{
StringBuilder hex = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
hex.AppendFormat("{0:X2}", b);
}
return hex.ToString();
}
/// <summary>
/// 计算SM3哈希值
/// </summary>
private string ComputeSm3Hash(string input)
{
byte[] msg = Encoding.UTF8.GetBytes(input);
SM3Digest digest = new SM3Digest();
digest.BlockUpdate(msg, 0, msg.Length);
byte[] result = new byte[digest.GetDigestSize()];
digest.DoFinal(result, 0);
return Hex.ToHexString(result).ToUpper();
}
#endregion
2025-07-02 09:35:20 +08:00
}
}