2025-10-30 16:09:44 +08:00

92 lines
3.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System.Security.Cryptography;
using System.Text;
namespace YD_AllHeartRates.Api.Utilities
{
public static class DataEncryptHelper
{
/// <summary>
/// SM2 公钥加密C1C3C2 顺序,输出十六进制)
/// </summary>
/// <param name="plainText">明文字符串</param>
/// <param name="pubKeyHex">公钥十六进制(压缩或非压缩)</param>
/// <returns>加密后的十六进制密文</returns>
public static string EncryptSm2(string plainText, string pubKeyHex)
{
if (string.IsNullOrEmpty(plainText))
throw new ArgumentException("plainText 不能为空");
if (string.IsNullOrEmpty(pubKeyHex))
throw new ArgumentException("pubKeyHex 不能为空");
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
// 获取 SM2 曲线参数
var sm2Curve = GMNamedCurves.GetByName("sm2p256v1");
var curve = sm2Curve.Curve;
var ecParams = new ECDomainParameters(curve, sm2Curve.G, sm2Curve.N);
// 解析公钥
byte[] pubKeyBytes = HexStringToBytes(pubKeyHex);
if (pubKeyBytes.Length != 33 && pubKeyBytes.Length != 65)
throw new ArgumentException("公钥长度错误,应为 33压缩或 65非压缩字节");
Org.BouncyCastle.Math.EC.ECPoint q;
try
{
q = curve.DecodePoint(pubKeyBytes);
}
catch (Exception ex)
{
throw new ArgumentException("公钥解析失败,请确认是有效 SM2 公钥(压缩或非压缩)", ex);
}
var pubKey = new ECPublicKeyParameters(q, ecParams);
// SM2 加密C1C3C2
var engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
engine.Init(true, new ParametersWithRandom(pubKey, new SecureRandom()));
byte[] cipherBytes = engine.ProcessBlock(plainBytes, 0, plainBytes.Length);
return BytesToHex(cipherBytes);
}
#region
/// <summary>
/// 十六进制字符串转字节数组
/// </summary>
private static byte[] HexStringToBytes(string hex)
{
if (hex.Length % 2 != 0)
throw new ArgumentException("Hex string 必须为偶数长度");
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
/// <summary>
/// 字节数组转十六进制字符串
/// </summary>
private static string BytesToHex(byte[] bytes)
{
StringBuilder sb = new StringBuilder(bytes.Length * 2);
foreach (var b in bytes)
sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
#endregion
}
}