示例#1
0
        /// <summary>
        /// 以CBC模式加密明文二进制数组
        /// </summary>
        /// <param name="iv">输出本次加密使用的初始向量。算法会使用Randomizer成员初始化这个数组</param>
        /// <param name="plain">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>加密后的数据块(不包括初始向量)</returns>
        public static byte[] EncryptCBC(this IBlockEncryption enc, out byte[] iv, byte[] plain, byte[] key)
        {
            int BlockSize = enc.BlockSize;

            byte[] p = enc.Padder(plain);
            iv = new byte[BlockSize];
            enc.Randomizer(iv); Debug.Print(iv.ToHexString());

            int block_count = p.Length / BlockSize;

            for (int i = 0; i < block_count; i++)
            {
                int this_block = i * BlockSize;
                int pre_block  = this_block - BlockSize;

                if (i == 0)
                {
                    XorBlock(enc, iv, 0, p, this_block);
                }
                else
                {
                    XorBlock(enc, p, pre_block, p, this_block);
                }
                enc.Encryptor(p, this_block, key);
            }
            return(p);
        }
示例#2
0
        /// <summary>
        /// 以EBC模式解密密文二进制数组
        /// </summary>
        /// <param name="cipher">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static byte[] DecryptEBC(this IBlockEncryption enc, byte[] cipher, byte[] key)
        {
            int BlockSize = enc.BlockSize;

            byte[] c           = (byte[])cipher.Clone();
            int    block_count = c.Length / BlockSize;

            for (int i = block_count - 1; i > 0; i--)
            {
                enc.Decryptor(c, i * BlockSize, key);
            }
            return(c);
        }
示例#3
0
        /// <summary>
        /// 以EBC模式加密明文二进制数组
        /// </summary>
        /// <param name="plain">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>密文</returns>
        public static byte[] EncryptEBC(this IBlockEncryption enc, byte[] plain, byte[] key)
        {
            int BlockSize = enc.BlockSize;

            byte[] p           = enc.Padder(plain);
            int    block_count = p.Length / BlockSize;

            for (int i = 0; i < block_count; i++)
            {
                enc.Encryptor(p, i * BlockSize, key);
            }
            return(p);
        }
示例#4
0
        private static void XorBlock(IBlockEncryption enc, byte[] left, int left_index, byte[] right, int right_index)
        {
            int BlockSize = enc.BlockSize;

            if (left_index + BlockSize > left.Length)
            {
                throw new Exception($"异或式的左值长度不足,索引[{left_index}]之后的数据长度不足{BlockSize}");
            }
            else if (right_index + BlockSize > right.Length)
            {
                throw new Exception($"异或式的右值长度不足,索引[{right_index}]之后的数据长度不足{BlockSize}");
            }

            for (int i = 0; i < enc.BlockSize; i++)
            {
                right[right_index + i] = (byte)(left[left_index + i] ^ right[right_index + i]);
            }
        }
示例#5
0
        /// <summary>
        /// 以CBC模式解密密文二进制数组
        /// </summary>
        /// <param name="iv">初始向量。用于解密第一个数据块</param>
        /// <param name="cipher">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>解密后的数据块(不包括初始向量)</returns>
        public static byte[] DecryptCBC(this IBlockEncryption enc, byte[] iv, byte[] cipher, byte[] key)
        {
            int BlockSize = enc.BlockSize;

            byte[] c           = (byte[])cipher.Clone();
            int    block_count = c.Length / BlockSize;

            for (int i = block_count - 1; i >= 0; i--)
            {
                int this_block = i * BlockSize;
                int pre_block  = this_block - BlockSize;

                enc.Decryptor(c, this_block, key);
                if (i == 0)
                {
                    XorBlock(enc, iv, 0, c, this_block);
                }
                else
                {
                    XorBlock(enc, c, pre_block, c, this_block);
                }
            }
            return(c);
        }