using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Paddings; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace Infrastructure.Helpers { public class SM4CryptoHelper { const int SM4_KEY_SIZE = 128 / 8; // 16 bytes const int BLOCK_SIZE = 16; // SM4 block size is 16 bytes #region 随机密钥 /// /// sm4 随机密钥 /// /// public static byte[] GenerateSM4Key() { using (var rng = RandomNumberGenerator.Create()) { byte[] key = new byte[SM4_KEY_SIZE]; rng.GetBytes(key); return key; } } #endregion #region CBC模式,PKCS7填充 // 生成随机IV public static byte[] GenerateIV() { using (var rng = RandomNumberGenerator.Create()) { byte[] iv = new byte[BLOCK_SIZE]; rng.GetBytes(iv); return iv; } } // SM4加密 (CBC模式,PKCS7填充) public static byte[] SM4Encrypt(byte[] key, byte[] iv, byte[] plaintext) { // 创建加密器 var engine = new SM4Engine(); var blockCipher = new CbcBlockCipher(engine); var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding()); var keyParam = new KeyParameter(key); var keyParamWithIv = new ParametersWithIV(keyParam, iv); // 初始化加密器 cipher.Init(true, keyParamWithIv); // 处理数据 byte[] output = new byte[cipher.GetOutputSize(plaintext.Length)]; int len = cipher.ProcessBytes(plaintext, 0, plaintext.Length, output, 0); len += cipher.DoFinal(output, len); // 返回正确长度的密文 if (len < output.Length) { byte[] result = new byte[len]; Array.Copy(output, 0, result, 0, len); return result; } return output; } // SM4解密 (CBC模式,PKCS7填充) public static byte[] SM4Decrypt(byte[] key, byte[] iv, byte[] ciphertext) { // 创建解密器 var engine = new SM4Engine(); var blockCipher = new CbcBlockCipher(engine); var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding()); var keyParam = new KeyParameter(key); var keyParamWithIv = new ParametersWithIV(keyParam, iv); // 初始化解密器 cipher.Init(false, keyParamWithIv); // 处理数据 byte[] output = new byte[cipher.GetOutputSize(ciphertext.Length)]; int len = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, output, 0); len += cipher.DoFinal(output, len); // 返回正确长度的明文 if (len < output.Length) { byte[] result = new byte[len]; Array.Copy(output, 0, result, 0, len); return result; } return output; } #endregion #region ECB加密(PKCS#7填充) // SM4 ECB加密(PKCS#7填充) public static byte[] Encrypt(byte[] key, byte[] plaintext) { if (key == null || key.Length != BLOCK_SIZE) throw new ArgumentException("Key must be 16 bytes (128 bits)"); // 创建加密器 var engine = new SM4Engine(); var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding()); cipher.Init(true, new KeyParameter(key)); // 处理数据 byte[] output = new byte[cipher.GetOutputSize(plaintext.Length)]; int len = cipher.ProcessBytes(plaintext, 0, plaintext.Length, output, 0); len += cipher.DoFinal(output, len); // 返回正确长度的密文 if (len < output.Length) { byte[] result = new byte[len]; Buffer.BlockCopy(output, 0, result, 0, len); return result; } return output; } // SM4 ECB解密(PKCS#7填充) public static byte[] Decrypt(byte[] key, byte[] ciphertext) { if (key == null || key.Length != BLOCK_SIZE) throw new ArgumentException("Key must be 16 bytes (128 bits)"); // 创建解密器 var engine = new SM4Engine(); var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding()); cipher.Init(false, new KeyParameter(key)); // 处理数据 byte[] output = new byte[cipher.GetOutputSize(ciphertext.Length)]; int len = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, output, 0); len += cipher.DoFinal(output, len); // 返回正确长度的明文 if (len < output.Length) { byte[] result = new byte[len]; Buffer.BlockCopy(output, 0, result, 0, len); return result; } return output; } #endregion //// SM2加密 //public static byte[] SM2Encrypt(byte[] publicKey, byte[] data) //{ // var curve = Org.BouncyCastle.Asn1.GM.GMNamedCurves.GetByName("sm2p256v1"); // var domainParams = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); // var q = curve.Curve.DecodePoint(publicKey); // var pubKey = new ECPublicKeyParameters(q, domainParams); // var cipher = new SM2Engine(new SM3Digest()); // cipher.Init(true, new ParametersWithRandom(pubKey, new SecureRandom())); // return cipher.ProcessBlock(data, 0, data.Length); //} //// SM2解密 //public static byte[] SM2Decrypt(byte[] privateKey, byte[] encryptedData) //{ // var curve = Org.BouncyCastle.Asn1.GM.GMNamedCurves.GetByName("sm2p256v1"); // var domainParams = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); // var d = new BigInteger(1, privateKey); // var privKey = new ECPrivateKeyParameters(d, domainParams); // var cipher = new SM2Engine(new SM3Digest()); // cipher.Init(false, privKey); // return cipher.ProcessBlock(encryptedData, 0, encryptedData.Length); //} } }