You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.7 KiB
C#

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 随机密钥
/// <summary>
/// sm4 随机密钥
/// </summary>
/// <returns></returns>
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);
//}
}
}