AES 256 加密和解密 for C#

来源:互联网 发布:android ndk linux 32 编辑:程序博客网 时间:2024/06/05 06:50

这几天在写一个对文件进行加密解密的程序,翻了以前在博客园贴过的一段代码,稍微整理了一下,写成一个方便调用的类,并做了注释。

这里需要特别说明的是,AES 需要提供2个字符串,一个是KEY,一个是IV,并且都有长度要求。但对于一般的加密来说,是比较麻烦的。所以我还提供了一个方便调用的 Simple 方法,只需提供一个密码,通过 MD5 自动处理为 32 位长度的 KEY,并截取其中 16 位作为 IV,这样在调用的时候,也方便许多。

经过试用,觉得 AES 256 在加密小文件的时候,效率是可以的,但加密大文件(例如 1.25G 的视频)效率明显下降,并且占用系统资源很大。

以下是代码:

using System.Security.Cryptography;using System.Text; // 阿博-STYLE// www.abo-style.comnamespace AboStyle{    /// <summary>    /// AES 256 加密和解密 for C#    /// 阿博-STYLE(2012)    /// </summary>    public class Aes    {        #region Create        /// <summary>        /// 创建一个统一配置的加密算法。        /// </summary>        /// <param name="key">密钥(32位)</param>        /// <param name="iv">初始化向量(16位)</param>        /// <returns>RijndaelManaged</returns>        private static RijndaelManaged Create(string key, string iv)        {            RijndaelManaged rm = new RijndaelManaged();            rm.Key = Encoding.UTF8.GetBytes(key);   // 这里统一使用UTF8进行编码;            rm.IV = Encoding.UTF8.GetBytes(iv);     // 如果使用其它编码,要注意长度问题;            rm.Mode = CipherMode.CBC;            rm.Padding = PaddingMode.PKCS7;            return rm;        }        #endregion         #region Encryptor        /// <summary>        /// 对字节数组进行加密        /// </summary>        /// <param name="bs">要加密的字节</param>        /// <param name="key">密钥(32位)</param>        /// <param name="iv">初始化向量(16位)</param>        /// <returns>加密后的结果</returns>        public static byte[] Encryptor(byte[] bs, string key, string iv)        {            ICryptoTransform transform = Create(key, iv).CreateEncryptor();            return transform.TransformFinalBlock(bs, 0, bs.Length);        }        #endregion         #region Decryptor        /// <summary>        /// 对字节数组进行解密        /// </summary>        /// <param name="bs">要解密的字节</param>        /// <param name="key">密钥(32位)</param>        /// <param name="iv">初始化向量(16位)</param>        /// <returns>解密后的结果</returns>        public static byte[] Decryptor(byte[] bs, string key, string iv)        {            ICryptoTransform transform = Create(key, iv).CreateDecryptor();            return transform.TransformFinalBlock(bs, 0, bs.Length);        }        #endregion         #region Simple        /// <summary>        /// 方便简单调用的加密或解密统一方法        /// </summary>        /// <param name="encrypt">是否为加密?true 为加密,false 为解密</param>        /// <param name="bs">要加密或解密的字节</param>        /// <param name="password">密码(任意长度,使用MD5处理为32位)</param>        /// <returns>处理后的字节</returns>        public static byte[] Simple(bool encrypt, byte[] bs, string password)        {            // 借用 MD5 算法,将密码统一为32位长度字符串            StringBuilder md5 = new StringBuilder();            foreach (byte b in System.Security.Cryptography.MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(password)))            {                md5.Append(b.ToString("X2"));            }             // KEY 为 MD5            string key = md5.ToString();             // IV 为 MD5 中截取中间的16位字符            string iv = key.Substring(8, 16);             // 根据是否加密 调用不同的方法            return encrypt ? Encryptor(bs, key, iv) : Decryptor(bs, key, iv);        }        #endregion    }}