首页 > 编程语言 > 详细

整理SM4国密算法

时间:2020-05-11 18:55:37      阅读:144      评论:0      收藏:0      [点我收藏+]
     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];
        }
    }

  

整理SM4国密算法

原文:https://www.cnblogs.com/yzpopulation/p/12870536.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!