|
|
|
|
using NPOI.POIFS.Crypt.Dsig;
|
|
|
|
|
using Org.BouncyCastle.Crypto.Signers;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Buffers.Text;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reactive;
|
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.Unicode;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Infrastructure.Helpers
|
|
|
|
|
{
|
|
|
|
|
public class EncryptionHelper
|
|
|
|
|
{
|
|
|
|
|
String privateKey = "ABA4354EFAFE944C2F226A3981C7DC70F43BD6053EDA83F4DC274242BBB23CAA";
|
|
|
|
|
String publicKey = "04F1BF1BEFD63F16E5DB3BCD32CA5D9A8E8DF7ADD67D6C4F293FB23F7BDA74F52D31B8DDAD03D955D566505A15D8B7DBE83B42378B8E8749C0EB6E2FBC8675838B";
|
|
|
|
|
string publickey = "04D6974E2384ECE39F5ADF1473E4B9B60E0D438A6F701F667C0C88D25BE2F8508A3AAFF9D9500ECFFD8E79B2DE58C024B689B5C207486646EA08A352FBB0016D46";
|
|
|
|
|
byte[] sm4Key = null;
|
|
|
|
|
public EncryptionHelper()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取x-lc-secret
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public string getxseret()
|
|
|
|
|
{
|
|
|
|
|
if (sm4Key == null)
|
|
|
|
|
{
|
|
|
|
|
sm4Key = SM4CryptoHelper.GenerateSM4Key();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//十六进制字符串 → 字节数组 publickey
|
|
|
|
|
byte[] publickeybyte = HexToBytes(publickey);
|
|
|
|
|
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>
|
|
|
|
|
public string Decrypt(byte[] x_lc_screte,byte[] output)
|
|
|
|
|
{
|
|
|
|
|
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 = "";
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(str))
|
|
|
|
|
{
|
|
|
|
|
string[] tokenstr = str.Split(".");
|
|
|
|
|
signData=tokenstr[2];
|
|
|
|
|
needSignData = tokenstr[0] + tokenstr[1];
|
|
|
|
|
}
|
|
|
|
|
byte[] signbyte=Convert.FromBase64String(signData);
|
|
|
|
|
byte[] needSignDataByte = Encoding.UTF8.GetBytes(needSignData);
|
|
|
|
|
// 4. SM2验签 publickey
|
|
|
|
|
byte[] publickeybyte = HexToBytes(publickey);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return SM2CryptoHelper.Verify(publickeybyte, needSignDataByte, signbyte);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("SM2签名失败", ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|