LASAPlatform/Infrastructure/Helpers/EncryptionHelper.cs

225 lines
7.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using NPOI.POIFS.Crypt.Dsig;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
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;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Asn1;
namespace Infrastructure.Helpers
{
public class EncryptionHelper
{
//String privateKey = "ABA4354EFAFE944C2F226A3981C7DC70F43BD6053EDA83F4DC274242BBB23CAA";
String privateKey = "32E324B2FBA5A6CF0D4645EE2D6B3295A6D9D3682C172B2D32E95EDD04340EF1";
//String publicKey = "04F1BF1BEFD63F16E5DB3BCD32CA5D9A8E8DF7ADD67D6C4F293FB23F7BDA74F52D31B8DDAD03D955D566505A15D8B7DBE83B42378B8E8749C0EB6E2FBC8675838B";
//string publickey = "04D6974E2384ECE39F5ADF1473E4B9B60E0D438A6F701F667C0C88D25BE2F8508A3AAFF9D9500ECFFD8E79B2DE58C024B689B5C207486646EA08A352FBB0016D46";
//string publickey = "04CF7CAE31B5130D1D5D1AC1DC2778D94533868A8D57FC02BBD97B688E07145DAAA96462DC83D9F348261F738D51C049770C43BA53B584917C9E30C6221B737CDD";
string publickey = "04D9D42CFD9633871B5540A4C891A6230A872EBB661FD2537C19817052728143AF53FEF4B38FCF8C2395C237308B7B8C21D93E94FE34E826220580D7BAFCD5F04B";
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;
}
#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
}
}