1. 程式人生 > >c# AES DES MD5加密演算法

c# AES DES MD5加密演算法

MD5加密封裝

  MD5常用加密FormsAuthentication.HashPasswordForStoringInConfigFile在Net Freamwork4.5以後就不在支援,下面整理了32位或16位下的幾個方法,以及不同寫法,最後一個由從老版本遷移過來,後續淘汰不用。

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace NC.Common
{
    /// <summary>
    /// 此類獲取md5加密值均為大寫,如果要獲取小寫:MD5Comm.Get32MD5One(xx).ToLower();或完善此類。
    /// </summary>
    public class MD5Comm
    {
        #region --Expired code--
        ///// <summary>
        ///// MD5加密
        ///// </summary>
        //public string Md5(string txt)
        //{
        //    //return FormsAuthentication.HashPasswordForStoringInConfigFile(txt, "MD5");//此方法nf4.5後不再支援
        //}
        //public string Md5Pass(string pwd)
        //{
        //    return Md5(pwd + "Jiahao");
        //} 
        #endregion

        /// <summary>
        /// 此程式碼示例通過建立雜湊字串適用於任何 MD5 雜湊函式 (在任何平臺) 上建立 32 個字元的十六進位制格式雜湊字串
        /// 官網案例改編
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Get32MD5One(string source)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source));
                StringBuilder sBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }

                string hash = sBuilder.ToString();
                return hash.ToUpper();
            }
        }
        /// <summary>
        /// 獲取16位md5加密
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Get16MD5One(string source)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source));
                //轉換成字串,並取9到25位
                string sBuilder = BitConverter.ToString(data, 4, 8);
                //BitConverter轉換出來的字串會在每個字元中間產生一個分隔符,需要去除掉
                sBuilder = sBuilder.Replace("-", "");
                return sBuilder.ToString().ToUpper();
            }
        }
        //// <summary>
        /// </summary>
        /// <param name="strSource">需要加密的明文</param>
        /// <returns>返回32位加密結果,該結果取32位加密結果的第9位到25位</returns>
        public static string Get32MD5Two(string source)
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            //獲取密文位元組陣列
            byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source));
            //轉換成字串,32位
            string strResult = BitConverter.ToString(bytResult);
            //BitConverter轉換出來的字串會在每個字元中間產生一個分隔符,需要去除掉
            strResult = strResult.Replace("-", "");
            return strResult.ToUpper();
        }
        //// <summary>
        /// </summary>
        /// <param name="strSource">需要加密的明文</param>
        /// <returns>返回16位加密結果,該結果取32位加密結果的第9位到25位</returns>
        public static string Get16MD5Two(string source)
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            //獲取密文位元組陣列
            byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source));
            //轉換成字串,並取9到25位
            string strResult = BitConverter.ToString(bytResult, 4, 8);
            //BitConverter轉換出來的字串會在每個字元中間產生一個分隔符,需要去除掉
            strResult = strResult.Replace("-", "");
            return strResult.ToUpper();
        }
        /// <summary>
        /// 自定義MD5函式,32位,從老版本遷移過來,後續淘汰不用。與Get32MD5One重複
        /// </summary>
        public static string Get32MD5Old(string str)
        {
            byte[] b = Encoding.UTF8.GetBytes(str);
            b = new MD5CryptoServiceProvider().ComputeHash(b);
            string ret = "";
            for (int i = 0; i < b.Length; i++)
                ret += b[i].ToString("x").PadLeft(2, '0');

            return ret.ToUpper();
        }
    }
}

AES的加密、解密

  上面我們介紹了MD5加密封裝,接下來分享給大家供大家參考一下AES加密、解密,AES要注意的是32位密匙。AES 加密解密(高階加密標準,是下一代的加密演算法標準,速度快,安全級別高,目前 AES 標準的一個實現是 Rijndael 演算法)

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace NC.Common
{
    /// <summary> 
    /// 加密
    /// </summary> 
    public class AES
    {
        //預設金鑰向量
        private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F };

        public static string Encode(string encryptString, string encryptKey)
        {
            encryptKey = GetSubString(encryptKey,0, 32, "");
            encryptKey = encryptKey.PadRight(32, ' ');

            RijndaelManaged rijndaelProvider = new RijndaelManaged();
            rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32));
            rijndaelProvider.IV = Keys;
            ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor();

            byte[] inputData = Encoding.UTF8.GetBytes(encryptString);
            byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length);

            return Convert.ToBase64String(encryptedData);
        }

        public static string Decode(string decryptString, string decryptKey)
        {
            try
            {
                decryptKey = GetSubString(decryptKey,0, 32, "");
                decryptKey = decryptKey.PadRight(32, ' ');

                RijndaelManaged rijndaelProvider = new RijndaelManaged();
                rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);
                rijndaelProvider.IV = Keys;
                ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor();

                byte[] inputData = Convert.FromBase64String(decryptString);
                byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length);

                return Encoding.UTF8.GetString(decryptedData);
            }
            catch
            {
                return "";
            }

        }

        public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)
        {
            string myResult = p_SrcString;

            Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString);
            foreach (char c in Encoding.UTF8.GetChars(bComments))
            {    //當是日文或韓文時(注:中文的範圍:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韓文為\xAC00-\xD7A3)
                if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3'))
                {
                    //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
                    //當擷取的起始位置超出欄位串長度時
                    if (p_StartIndex >= p_SrcString.Length)
                        return "";
                    else
                        return p_SrcString.Substring(p_StartIndex,
                                                       ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length);
                }
            }

            if (p_Length >= 0)
            {
                byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString);

                //當字串長度大於起始位置
                if (bsSrcString.Length > p_StartIndex)
                {
                    int p_EndIndex = bsSrcString.Length;

                    //當要擷取的長度在字串的有效長度範圍內
                    if (bsSrcString.Length > (p_StartIndex + p_Length))
                    {
                        p_EndIndex = p_Length + p_StartIndex;
                    }
                    else
                    {   //當不在有效範圍內時,只取到字串的結尾

                        p_Length = bsSrcString.Length - p_StartIndex;
                        p_TailString = "";
                    }

                    int nRealLength = p_Length;
                    int[] anResultFlag = new int[p_Length];
                    byte[] bsResult = null;

                    int nFlag = 0;
                    for (int i = p_StartIndex; i < p_EndIndex; i++)
                    {
                        if (bsSrcString[i] > 127)
                        {
                            nFlag++;
                            if (nFlag == 3)
                                nFlag = 1;
                        }
                        else
                            nFlag = 0;

                        anResultFlag[i] = nFlag;
                    }

                    if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1))
                        nRealLength = p_Length + 1;

                    bsResult = new byte[nRealLength];

                    Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength);

                    myResult = Encoding.Default.GetString(bsResult);
                    myResult = myResult + p_TailString;
                }
            }

            return myResult;
        }

    }
}

DES加密/解密

  除了MD5加密、AES加密/解密之外還經常用到DES加密、解密,注意的是DES的密匙是8位的,這裡有家婆MD5加密一起使用。

using System;
using System.Security.Cryptography;
using System.Text;

namespace NC.Common
{
    /// <summary>
    /// DES加密/解密類。
    /// </summary>
    public class DESEncrypt
    {

        #region --加密--

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Encrypt(string Text)
        {
            return Encrypt(Text, "ncmvc");
        }
        /// <summary> 
        /// 加密資料 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string Encrypt(string Text, string sKey)
        {
            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray;
                inputByteArray = Encoding.Default.GetBytes(Text);
                string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8);
                des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                return ret.ToString();
            }
            catch { return "error"; }
        }

        #endregion

        #region --解密--

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Decrypt(string Text)
        {
            return Decrypt(Text, "ncmvc");
        }
        /// <summary> 
        /// 解密資料 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string Decrypt(string Text, string sKey)
        {
            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                int len;
                len = Text.Length / 2;
                byte[] inputByteArray = new byte[len];
                int x, i;
                for (x = 0; x < len; x++)
                {
                    i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                    inputByteArray[x] = (byte)i;
                }
                string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8);
                des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return Encoding.Default.GetString(ms.ToArray());
            }
            catch { return "error"; }
        }

        #endregion

    }
}