public class Sm4Encryptor
{
public byte[] KeyBytes = new byte[16];
private Sm4Encryptor()
{
sm4 = new SM4Engine();
}
public SM4Engine sm4 { get; set; }
private static Sm4Encryptor UniqueInstance { get; set; }
public static Sm4Encryptor GetInstance()
{
return UniqueInstance ??= new Sm4Encryptor();
}
public void SetKey(byte[] bytes)
{
if (bytes.Length > 16) throw new Exception("Key Size Must 128 bit (16 bytes)");
Array.Copy(bytes, KeyBytes, bytes.Length);
}
public void SetKey(string key)
{
SetKey(Encoding.UTF8.GetBytes(key));
}
public byte[] DoEncrypt(byte[] plainBytes, byte[] keyBytes = null)
{
keyBytes ??= KeyBytes;
sm4.Init(true, new KeyParameter(keyBytes));
var blockSize = sm4.GetBlockSize();
var plainSize = plainBytes.Length;
byte[] outBytes = null;
var times = plainSize / blockSize;
if (times * blockSize != plainSize) outBytes = new byte[(times + 1) * blockSize];
for (var i = 0; i < times; i++) sm4.ProcessBlock(plainBytes, 16 * i, outBytes, 16 * i);
if (times * blockSize != plainSize)
{
var tmpInBytes = new byte[16];
var start = 16 * times;
Buffer.BlockCopy(plainBytes[start..], 0, tmpInBytes, 0, plainSize - start);
sm4.ProcessBlock(tmpInBytes, 0, outBytes, start);
}
return outBytes;
}
public byte[] DoDecrypt(byte[] encryptBytes, byte[] keyBytes = null)
{
keyBytes ??= KeyBytes;
sm4.Init(false, new KeyParameter(keyBytes));
var blockSize = sm4.GetBlockSize();
var encryptSize = encryptBytes.Length;
var times = encryptSize / blockSize;
if (times * blockSize != encryptSize) throw new Exception("Length Size Must Mod 16 Zero!");
var outBytes = new byte[encryptSize];
for (var i = 0; i < times; i++) sm4.ProcessBlock(encryptBytes, 16 * i, outBytes, 16 * i);
return Decode(outBytes);
}
private static byte[] Decode(byte[] packet)
{
var i = packet.Length;
do
{
i--;
} while (packet[i] == 0);
i++;
return packet[..i];
}
}
原文:https://www.cnblogs.com/yzpopulation/p/12870536.html