需要引用的命名空间
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 Org.BouncyCastle.Utilities.Encoders;
关键代码
public class SM4Helper
{
public static void GenerateKeyHex(out string key, out string iv)
{
//生成对称加密算法
var keyGenerator = new CipherKeyGenerator();
keyGenerator.Init(new KeyGenerationParameters(new SecureRandom(), 128));
var a = keyGenerator.GenerateKey();
key = Hex.ToHexString(a);
SecureRandom random = new SecureRandom();
byte[] b = new byte[16]; // IV长度为16字节
random.NextBytes(b);
iv = Hex.ToHexString(b);
}
public static byte[] ECBEncrypt(byte[] input, string key)
{
var engine = new SM4Engine();
var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
KeyParameter keyParam = new KeyParameter(Decode(key));
cipher.Init(true, keyParam);
var output = new byte[cipher.GetOutputSize(input.Length)];
int length = cipher.ProcessBytes(input, 0, input.Length, output, 0);
cipher.DoFinal(output, length);
return output;
}
public static byte[] ECBDecrypt(byte[] input, string key)
{
var engine = new SM4Engine();
var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
KeyParameter keyParam = new KeyParameter(Decode(key));
cipher.Init(false, keyParam);
var output = new byte[cipher.GetOutputSize(input.Length)];
int length = cipher.ProcessBytes(input, 0, input.Length, output, 0);
cipher.DoFinal(output, length);
return RemovePadding(output);
}
public static byte[] CBCEncrypt(byte[] plaintext, string key, string iv)
{
IBufferedCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new SM4Engine()), new Pkcs7Padding());
cipher.Init(true, new ParametersWithIV(new KeyParameter(Decode(key)), Decode(iv)));
byte[] output = new byte[cipher.GetOutputSize(plaintext.Length)];
int bytesProcessed = cipher.ProcessBytes(plaintext, 0, plaintext.Length, output, 0);
cipher.DoFinal(output, bytesProcessed);
return output;
}
public static byte[] CBCDecrypt(byte[] ciphertext, string key, string iv)
{
IBufferedCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new SM4Engine()), new Pkcs7Padding());
cipher.Init(false, new ParametersWithIV(new KeyParameter(Decode(key)), Decode(iv)));
byte[] output = new byte[cipher.GetOutputSize(ciphertext.Length)];
int bytesProcessed = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, output, 0);
cipher.DoFinal(output, bytesProcessed);
return RemovePadding(output);
}
public static byte[] RemovePadding(byte[] data)
{
int lastNonZeroByte = data.Length - 1;
while (data[lastNonZeroByte] == 0)
{
lastNonZeroByte--;
}
byte[] result = new byte[lastNonZeroByte + 1];
Array.Copy(data, result, lastNonZeroByte + 1);
return result;
}
public static byte[] Decode(string key)
{
return Regex.IsMatch(key, "^[0-9a-f]+$", RegexOptions.IgnoreCase) ? Hex.Decode(key) : Convert.FromBase64String(key);
}
}
代码调用:
var encrypted = SM4Helper.ECBEncrypt(Encoding.UTF8.GetBytes(plainText), this.secret);
Convert.ToBase64String(encrypted);