C# AES数据加密

使用对称加密算法AES
加密通常有对称加密(DES、AES)、非对称加密(RSA)、单向加密(MD5不可复原),非对称算法很安全但是速度慢一般用于传输对称加密的秘钥,本文主要介绍C#如何使用基于AES标准的Rijndael算法对数据包进行加密传输。

RijndaelManaged类为Rijndael算法管理类。这里有几个主要参数,单位都是bit:BlockSize、FeedbackSize、KeySize、Mode、Padding。这些参数可以影响私钥和IV长度,以及数据加密方式等。

ICryptoTransform为数据转换接口,有TransformBlock和TransformFinalBlock两个方法,这两个方法基本一样,主要是TransformBlock要求被处理数组需为InputBlockSize的整数倍,因为需要使用缓存减少GC这里在外部实现TransformFinalBlock中做的处理。

下方方法都是参照RijndaelManagedTransform.cs的源码实现的,对一个字节数组加密前需要先调用CheckBlock,返回值为存储加密后的数组大小。

        public static int CheckBlock(this NetDataWriter dataWriter, int offset)
        {
            int bodySize = dataWriter.WritePos - offset;//dataWriter.WritePos为数组大小,offset为偏移
            int inputBlockSize = NetConstants.BlockSize >> 3;
            int lonelyBytes = bodySize % inputBlockSize;
            int padSize = inputBlockSize - lonelyBytes;
            if (padSize != inputBlockSize)//官方TransformBlock里不会做这个判断
            {
                bodySize += padSize;
            }
            int packetSize = offset + bodySize + inputBlockSize;//EncryptData返回值为inputCount+padSize,TransformBlock前保证了数组为inputBlockSize的整数倍,所以padSize=inputBlockSize
            return packetSize;
        }
    public static int GetInputBlockSizeBytes(CipherMode cipherMode=NetConstants.ModeValue)
    {
        switch (cipherMode)
        {
            case CipherMode.ECB:
            case CipherMode.CBC:
                return NetConstants.BlockSize >> 3;

            case CipherMode.CFB:
                return NetConstants.FeedbackSize >> 3;

            default:
                throw new CryptographicException("Cryptography_InvalidCipherMode");
        }
    }

加密与解密操作

        public static int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset, byte[] Key, byte[] IV, bool needGenerateIV = true)
        {
            if (inputBuffer == null || inputBuffer.Length <= 0)
            {
                throw new Exception("inputBuffer is null or length is zero when encrypt");
            }
            if (Key == null || Key.Length != GetKeySizeBytes())
            {
                throw new Exception("private Key is null or length less than key size when encrypt");
            }
            if (IV == null || IV.Length != GetBlockSizeBytes())
            {
                throw new Exception("the IV is null or length less than iv size when encrypt");
            }

            using (RijndaelManaged managed = new RijndaelManaged())
            {
                managed.BlockSize = NetConstants.BlockSize;
                managed.FeedbackSize = NetConstants.FeedbackSize;
                managed.KeySize = NetConstants.KeySize;

                if (needGenerateIV)
                {
                    managed.GenerateIV();
                    Buffer.BlockCopy(managed.IV, 0, IV, 0, IV.Length);
                }

                managed.Mode = NetConstants.ModeValue;
                managed.Padding = NetConstants.PaddingValue;
                using (ICryptoTransform encryptor = managed.CreateEncryptor(Key, IV))
                {
                    return encryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
                }
            }
        }

        public static int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset, byte[] Key, byte[] IV)
        {
            if (inputBuffer == null || inputBuffer.Length <= 0)
            {
                throw new Exception("inputBuffer is null or length is zero when decrypt");
            }
            if (Key == null || Key.Length != GetKeySizeBytes())
            {
                throw new Exception("private Key is null or length less than key size when decrypt");
            }
            if (IV == null || IV.Length != GetBlockSizeBytes())
            {
                throw new Exception("the IV is null or length less than IV size when decrypt");
            }

            using (RijndaelManaged managed = new RijndaelManaged())
            {
                managed.BlockSize = NetConstants.BlockSize;
                managed.FeedbackSize = NetConstants.FeedbackSize;
                managed.KeySize = NetConstants.KeySize;

                managed.Mode = NetConstants.ModeValue;
                managed.Padding = NetConstants.PaddingValue;
                using (ICryptoTransform encryptor = managed.CreateDecryptor(Key, IV))
                {
                    return encryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
                }
            }
        }

网络数据传输

你可能感兴趣的:(C# AES数据加密)