using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Xml;
using System.Data;
using System.Xml.Serialization;namespace DrivingBehaviorInfoService
{
    public class CryptoException : Exception
    {
        public CryptoException(string errmsg) : base(errmsg) { }
    }
    public sealed class CryptoObject
    {
        #region 加密
        private static byte[] Key;
        private static int keyLen;
        public static int KeyLength
        {
            get { return keyLen; }
        }
        public static void SetKey(byte[] key)
        {
            if (key.Length == keyLen)//相等
            {
                Key = key;
            }
            else if (key.Length > keyLen) //摘取
            {
                Key = Copy(key, null, 0, 0, keyLen);
            }
            else //key.Length < KeyLen,追加空白
            {
                byte[] nkey=new byte[keyLen];
                int i;
                for (i = 0; i < key.Length; i++)
                    nkey[i] = key[i];
                for (; i < keyLen; i++)
                    nkey[i] = 10;
                Key = nkey;
            }
        }        private static byte[] IV;
        private static int ivLen;
        public static int IVLength
        {
            get { return ivLen; }
        }
        public static void SetIV(byte[] iv)
        {
            IV = iv;
        }        //哈希块字节数
        private static int hashLen;
        public static int HashLength
        {
            get { return hashLen; }
        }        //加密文档块前空留字节数
        private static int FirstBlockLen;        public CryptoObject()
        {
            hashLen = new HMACSHA256().HashSize / 8;
            RijndaelManaged rm = new RijndaelManaged();
            ivLen =rm.BlockSize/8;
            keyLen=rm.KeySize/8;
            FirstBlockLen = ivLen+hashLen;
            SetKey(new byte[] { 100, 11, 121, 135, 19, 205, 126, 111, 210, 198, 166, 188 });
        }
        public static void GenerateKey()
        {
            RijndaelManaged RijMan = new RijndaelManaged();
            RijMan.GenerateKey();
            Key = RijMan.Key;
        }
        public static void GenerateIV()
        {
            RijndaelManaged RijMan = new RijndaelManaged();
            RijMan.GenerateIV();
            IV = RijMan.IV;
        }
        //计算数据(data)的哈希(hash)
        //并将IV和hash插入到数据前面,
        //并返回新的IV哈希数据组合(mixedData)
        public byte[] InsertFirstBlock(byte[] data)
        {
            byte[] hash = ComputeHash(data);
            //合并哈希值与数据
            byte[] mixedData = Copy(data, null, 0, FirstBlockLen, data.Length);
            Copy(hash, mixedData, 0, ivLen, hashLen);
            Copy(IV, mixedData, 0, 0, ivLen);
            return mixedData;
        }
        //计算数据(data)的哈希
        public byte[] ComputeHash(byte[] data)
        {
            //初始化键控哈希对象
            HMACSHA256 macsha256 = new HMACSHA256(Key);
            //计算数据哈希并返回
            return macsha256.ComputeHash(data);
        }
        //求数据(data)哈希,并与给定哈希(hash)比较,验证数据的完整性
        //相等返回真,否则返回假
        public bool CompareHash(byte[] hash, byte[] data)
        {
            // 初始化键控哈希对象
            HMACSHA256 myhmacsha256 = new HMACSHA256(Key);
            //计算数据哈希
            byte[] hasht = myhmacsha256.ComputeHash(data);
            for (int i = 0; i < hashLen; i++)
                if (hash[i] != hasht[i])
                    return false;
            return true;
        }
        //获得混合数据块(mixedData)中的哈希部分(hash)
        public byte[] GetHash(byte[] mixedData)
        {
            return Copy(mixedData, null, ivLen, 0, hashLen);
        }
        //获得混合数据块(mixedData)中的IV部分(IV)
        public byte[] GetIV(byte[] mixedData)
        {
            return Copy(mixedData, null, 0, 0, ivLen);
        }
        //获得哈希数据块(mixedData)中的数据部分(data)
        public byte[] GetData(byte[] mixedData)
        {
            return Copy(mixedData,null, FirstBlockLen, 0, mixedData.Length - FirstBlockLen);
        }
        //将数据转换为基64格式数据
        public byte[] ToBase64(byte[] from)
        {
            ToBase64Transform base64Transform = new ToBase64Transform();
            MemoryStream msBase64Encrypted = new MemoryStream();
            CryptoStream csB64Encrypt = new CryptoStream(msBase64Encrypted, base64Transform, CryptoStreamMode.Write);
            csB64Encrypt.Write(from, 0, from.Length);
            csB64Encrypt.FlushFinalBlock();
            return msBase64Encrypted.ToArray();
        }
        //将数据从基64格式转换为正常格式
        public byte[] FromBase64(byte[] from)
        {
            FromBase64Transform fromBase64Transform = new FromBase64Transform();
            MemoryStream msBase64Decrypt = new MemoryStream(from);
            CryptoStream csBase64Decrypt = new CryptoStream(msBase64Decrypt, fromBase64Transform, CryptoStreamMode.Read);
            byte[] unBase64Encrypt = new byte[from.Length];
            int getedNum = csBase64Decrypt.Read(unBase64Encrypt, 0, unBase64Encrypt.Length);
            return Copy(unBase64Encrypt, null, 0, 0, getedNum);//注意:fromEncrypt.Length>getedNum
        }
        //加密数据
        public byte[] Crypto(byte[] from)
        {
            //对from中数据使用RijndaelManaged加密
            RijndaelManaged rijn = new RijndaelManaged();
            //获得Rijndael算法加密器,实施加密
            ICryptoTransform encryptor = rijn.CreateEncryptor(Key, IV);
            //加密后的数据放到内存流对象中
            MemoryStream msRijnEncrypted = new MemoryStream();
            //在写过程中,实施Rijndael加密
            CryptoStream csRijnEncrypt = new CryptoStream(msRijnEncrypted, encryptor, CryptoStreamMode.Write);
            //写所有数据到加密器
            csRijnEncrypt.Write(from, 0, from.Length);
            csRijnEncrypt.FlushFinalBlock();
            //获得由方法加密后的字节数据            return msRijnEncrypted.ToArray();
        }
        //解密数据
        public byte[] Decrypto(byte[] from)
        {
            MemoryStream msRijnDecrypt = new MemoryStream(from);
            RijndaelManaged r = new RijndaelManaged();
            //使用与加密相同的Key和IV,获得解密器
            ICryptoTransform decryptor = r.CreateDecryptor(Key, IV);
            //解密基于Rijndael的加密数据
            CryptoStream csRijnDecrypt = new CryptoStream(msRijnDecrypt, decryptor, CryptoStreamMode.Read);            //解密后的数据的目的
            byte[] unRijnEncrypt = new byte[from.Length];
            //从解密器中读取数据(即解密)  
            int getedNum = csRijnDecrypt.Read(unRijnEncrypt, 0, unRijnEncrypt.Length);
            
            //注意:unRijnEncrypt.Length>getedNum
            return Copy(unRijnEncrypt, null, 0, 0, getedNum);
        }
        //复制字节数据。
        //当目的数组(to)为空引用,则产生之。
        //目的数组长度必须为toindex+count
        private static byte[] Copy(
            byte[] from,     //源数组
            byte[] to,         //目的数组
            int fromindex, //源开始索引
            int toindex,     //目的开始索引
            int count         //拷贝字节数
            )
        {
            if (to == null)
                to = new byte[toindex + count];
            for (int i = 0; i < count; i++)
                to[toindex + i] = from[fromindex + i];
            return to;
        }
        #endregion
        #region String加密方法
        public string ZoomString(string from)
        {
            System.Text.UTF8Encoding textConverter = new System.Text.UTF8Encoding();
            byte[] b = textConverter.GetBytes(from);
            CryptoObject.GenerateIV();
            return textConverter.GetString(ToBase64(InsertFirstBlock(Crypto(b))));
        }
        public string ZoomBackString(string from)
        {
            UTF8Encoding textConverter = new UTF8Encoding();
            byte[] mixedData = FromBase64(textConverter.GetBytes(from));
            byte[] hash = GetHash(mixedData);
            SetIV(GetIV(mixedData));
            byte[] data = GetData(mixedData);
            if (!CompareHash(hash, data))
                throw new Exception("数据在传输过程中被损坏。");
            byte[] a = Decrypto(data);
            return textConverter.GetString(a);
        }
        #endregion
    }
}
[code=csharp][/code]加密C#