C#对称加密

.NET库的System.Security.Cryptography命名空间中,包含多种加密数据的类,涉及多种加密算法。加密方法主要分为两大类:对称加密和不对称加密。

对称加密 

私钥算法以块为单位加密数据,一次加密一个数据块。因此对称加密支持数据流,是加密流数据的理想方式。
.NET类库使用的私钥算法有RC2、DES、TripleDES和Rijndael。这些算法通过加密将n字节的输入块转换为加密字节的输出块。如果要加密或解密字节序列,必须逐块进行。由于n很小(对于RC2、DES和TripleDES算法,n的值为8字节、16字节或24字节,默认值为16字节;对于Rijndael算法,n的值为32字节),因此每次加密的块的大小必须大于n。实际上,一次读入的数据块是否符合私钥算法要求的块的大小,如果不符合应该如何填充使其符合要求等情况,.NET类库提供的算法类本身会自动处理,编写程序时不需要考虑这些问题。

 为了保证数据的安全,.NET基类库中提供的私钥算法类使用称作密码块链(CBC,Cipher Block Chaining)的链模式,算法使用一个密钥和一个初始化向量(IV,Initialization Vector)对数据执行加密转换。密钥和初始化向量IV一起决定如何加密数据,以及如何将数据解密为原始数据。通信双方都必须知道这个密钥和初始化向量才能够加密和解密数据。

初始化向量IV的作用:防止随机产生的明文和密文相同

对称加密算法的优点是保密强度高,加、解密速度快,适合加密大量数据。攻击者如果对加密后的数据进行破译,惟一的办法就是对每个可能的密钥执行穷举搜索。而采用这种加密技术,即使使用最快的计算机执行这种搜索,耗费的时间也相当长。如果使用较大的密钥,破译将会更加困难。在实际应用中,加密数据采用的密钥一般都有时效性,比如几天更换一次密钥和IV,如果攻击者采用穷举法试图破译加密后的数据,等到好不容易试出了密钥,加密者早已采用新的密钥对网络中传输的数据进行加密了,因此利用穷举搜索的方法破译加密后的数据实际上是没有意义的。 

.NET Framework中,公共语言运行时CLR(Common Language Runtime)使用面向流的设计实现对称加密,该设计的核心是CryptoStream,实现CryptoStream的任何被加密的对象都可以和实现Stream的任何对象链接起来。实现对称加密算法的类有四种:
DESCryptoServiceProvider 
RC2CryptoServiceProvider 
RijndaelManaged 
TripleDESCryptoServiceProvider 

下面是TripleDES的一个基本操作

private void buttonOK_Click(object sender, EventArgs e)
        {
            string str = textBoxInput.Text;
            //加密
            try
            {
                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
                //随机生成密钥Key和初始化向量IV(也可以自己设定)
                tdes.GenerateKey();
                tdes.GenerateIV();
                textBoxKey.Text = Encoding.UTF8.GetString(tdes.Key);
                //得到加密后的字节流
                byte[] encryptedBytes = EncryptText(str, tdes.Key, tdes.IV);
                //显示加密后的字符串
                textBoxEncrypt.Text = Encoding.UTF8.GetString(encryptedBytes);
                //解密
                string decryptString = DecryptText(encryptedBytes, tdes.Key, tdes.IV);
                //显示解密后的字符串
                textBoxDecrypt.Text = decryptString;
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "出错");
            }
        }
        private byte[] EncryptText(string str, byte[] Key, byte[] IV)
        {
            //创建一个内存流
            MemoryStream memoryStream = new MemoryStream();
            //使用传递的私钥和IV创建加密流
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);
            //将传递的字符串转换为字节数组
            byte[] toEncrypt = Encoding.UTF8.GetBytes(str);
            try
            {
                //将字节数组写入加密流,并清除缓冲区
                cryptoStream.Write(toEncrypt, 0, toEncrypt.Length);
                cryptoStream.FlushFinalBlock();
                //得到加密后的字节数组
                byte[] encryptedBytes = memoryStream.ToArray();
                return encryptedBytes;
            }
            catch (CryptographicException err)
            {
                throw new Exception("加密出错:" + err.Message);
            }
            finally
            {
                cryptoStream.Close();
                memoryStream.Close();
            }
        }
        private string DecryptText(byte[] dataBytes, byte[] Key, byte[] IV)
        {
            //根据加密后的字节数组创建一个内存流
            MemoryStream memoryStream = new MemoryStream(dataBytes);
            //使用传递的私钥、IV和内存流创建解密流
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
                CryptoStreamMode.Read);
            //创建一个字节数组保存解密后的数据
            byte[] decryptBytes = new byte[dataBytes.Length];
            try
            {
                //从解密流中将解密后的数据读到字节数组中
                cryptoStream.Read(decryptBytes, 0, decryptBytes.Length);
                //得到解密后的字符串
                string decryptedString = Encoding.UTF8.GetString(decryptBytes);
                return decryptedString;
            }
            catch (CryptographicException err)
            {
                throw new Exception("解密出错:" + err.Message);
            }
            finally
            {
                cryptoStream.Close();
                memoryStream.Close();
            }
        }

 

posted @ 2012-07-03 07:41  广拓小程序  阅读(6769)  评论(0编辑  收藏  举报