using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Smime; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.EC; using Org.BouncyCastle.Crypto.Encodings; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Paddings; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Pqc.Crypto.Lms; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; using System; using System.Linq; using System.Text; /// /// 提供对国密标准(SM2, SM3, SM4)加密算法的支持。 /// public class GmCrypto { // SM2 密钥对,用于非对称加密和解密操作 private AsymmetricCipherKeyPair _sm2KeyPair; /// /// 构造函数,默认生成新的 SM2 密钥对。 /// public GmCrypto() { _sm2KeyPair = GenerateSm2KeyPair(); } /// /// /// /// sm2公匙 /// sm2私匙 public GmCrypto(string pubKey, string priKey) { _sm2KeyPair = new AsymmetricCipherKeyPair(ReadPublicKeyFromBase64(pubKey), ReadPrivateKeyFromBase64(priKey)); } /// /// 生成一个新的 SM2 密钥对。 /// public AsymmetricCipherKeyPair GenerateSm2KeyPair() { // 定义椭圆曲线参数(这里使用的是SM2默认的曲线) X9ECParameters ecParams = CustomNamedCurves.GetByName("sm2p256v1"); ECDomainParameters domainParams = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed()); // 创建密钥对生成器并初始化 var keyPairGenerator = GeneratorUtilities.GetKeyPairGenerator("EC"); var keyGenParam = new ECKeyGenerationParameters(domainParams, new SecureRandom()); keyPairGenerator.Init(keyGenParam); return keyPairGenerator.GenerateKeyPair(); } public (string pubKey, string priKey) GetSM2Key() { // 获取公私钥 ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters)_sm2KeyPair.Private; ECPublicKeyParameters publicKey = (ECPublicKeyParameters)_sm2KeyPair.Public; // 将公钥转换为Base64编码的字符串 string publicKeyString = Convert.ToBase64String(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey).GetDerEncoded()); // 将私钥转换为PKCS#8格式并Base64编码 PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey); string privateKeyString = Convert.ToBase64String(privateKeyInfo.GetDerEncoded()); return (publicKeyString, privateKeyString); } /// /// 读取公私匙 /// /// /// public ECPublicKeyParameters ReadPublicKeyFromBase64(string publicKeyBase64) { byte[] encodedPublicKey = Convert.FromBase64String(publicKeyBase64); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.GetInstance(encodedPublicKey); return (ECPublicKeyParameters)PublicKeyFactory.CreateKey(publicKeyInfo); } /// /// 读取私有钥匙 /// /// /// public ECPrivateKeyParameters ReadPrivateKeyFromBase64(string privateKeyBase64) { byte[] encodedPrivateKey = Convert.FromBase64String(privateKeyBase64); PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.GetInstance(encodedPrivateKey); return (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privateKeyInfo); } /// /// 使用 SM2 算法加密给定的数据字符串。 /// /// 要加密的数据字符串。 /// 返回加密后的字节数组。 public byte[] EncryptSm2(string data) { return EncryptWithSM2(data, (ECPublicKeyParameters)_sm2KeyPair.Public); } /// /// 使用 SM2 算法解密给定的加密数据。 /// /// 已加密的数据字节数组。 /// 返回解密后的原始数据字符串。 public string DecryptSm2(byte[] encryptedData) { return DecryptWithSM2(encryptedData, (ECPrivateKeyParameters)_sm2KeyPair.Private); } /// /// 使用SM2算法进行加密。 /// /// 要加密的字符串。 /// 用于加密的公钥。 /// 返回加密后的字节数组。 public static byte[] EncryptWithSM2(string data, ECPublicKeyParameters publicKey) { var cipher = new SM2Engine(); cipher.Init(true, new ParametersWithRandom(publicKey, new SecureRandom())); return cipher.ProcessBlock(Encoding.UTF8.GetBytes(data), 0, data.Length); } /// /// 使用SM2算法进行解密。 /// /// 要解密的字节数组。 /// 用于解密的私钥。 /// 返回解密后的字符串。 public static string DecryptWithSM2(byte[] encryptedData, ECPrivateKeyParameters privateKey) { var cipher = new SM2Engine(); cipher.Init(false, privateKey); var output = cipher.ProcessBlock(encryptedData, 0, encryptedData.Length); return Encoding.UTF8.GetString(output); } /// /// 使用 SM3 哈希算法计算给定消息的哈希值。 /// /// 要计算哈希的消息字符串。 /// 返回哈希结果的十六进制字符串表示形式。 public string HashSm3(string message) { var sm3Digest = new SM3Digest(); // 创建 SM3 摘要实例 byte[] messageBytes = Encoding.UTF8.GetBytes(message); // 将消息转换为字节数组 sm3Digest.BlockUpdate(messageBytes, 0, messageBytes.Length); // 更新摘要对象 byte[] hash = new byte[sm3Digest.GetDigestSize()]; // 准备存储哈希结果的空间 sm3Digest.DoFinal(hash, 0); // 完成哈希计算并获取结果 return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); // 转换为十六进制字符串 } /// /// 默认的 SM4 对称加密使用的密钥和初始化向量 (IV)。 /// 注意:在实际应用中应从安全的地方加载这些值。 /// private static readonly string DefaultKey = "your-16-byte-key"; // 128 bits private static readonly string DefaultIV = "your-16-byte-iv-"; // 128 bits /// /// 使用 SM4 算法加密数据 /// /// 要加密的明文 /// 16 字节的密钥 /// 16 字节的初始化向量(IV) /// 加密后的字节数组 public byte[] EncryptSM4(string plainText, string? key=null, string? iv = null) { if (string.IsNullOrEmpty(key)) key = DefaultKey; if (string.IsNullOrEmpty(iv)) iv = DefaultIV; // 将明文、密钥和 IV 转换为字节数组 byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv); // 获取 SM4/CBC/PKCS7Padding 模式的加密引擎 IBufferedCipher cipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding"); // 创建密钥参数 KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes); // 创建包含密钥和 IV 的参数 ParametersWithIV parameters = new ParametersWithIV(keyParam, ivBytes); // 初始化加密模式 cipher.Init(true, parameters); // 执行加密操作并返回加密后的字节数组 return cipher.DoFinal(inputBytes); } /// /// 使用 SM4 算法解密数据 /// /// 要解密的密文 /// 16 字节的密钥 /// 16 字节的初始化向量(IV) /// 解密后的字节数组 public byte[] DecryptSM4(byte[] cipherText, string? key=null, string? iv=null) { if (string.IsNullOrEmpty(key)) key = DefaultKey; if (string.IsNullOrEmpty(iv)) iv = DefaultIV; // 将密钥和 IV 转换为字节数组 byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv); // 获取 SM4/CBC/PKCS7Padding 模式的解密引擎 IBufferedCipher cipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding"); // 创建密钥参数 KeyParameter keyParam = ParameterUtilities.CreateKeyParameter("SM4", keyBytes); // 创建包含密钥和 IV 的参数 ParametersWithIV parameters = new ParametersWithIV(keyParam, ivBytes); // 初始化解密模式 cipher.Init(false, parameters); // 执行解密操作并返回解密后的字节数组 return cipher.DoFinal(cipherText); } }