zoukankan      html  css  js  c++  java
  • c# 加密

    引自: http://blog.csdn.net/leestar54/article/details/6743554

    数据的加密重要性大家皆知,很多情况下需要对数据进行加密处理,但各种重要数据的加密要求不一样,有些需要时可逆的,有些是不要求可逆的,可逆的一般称之为对称加密算法,不可逆的一般可以成为非对称加密算法。如登录密码,一般较好的方式是采用不可逆的加密算法,如MD5、SHA256、哈希数值等,当然也有的采用可逆的强度好一些的加密方式,在选择加密键值的时候,变化一下也算是比较不错的选择。另外一些为了掩人耳目或者不让别人直接可以查看到,就采用其他的加密算法,如DES加密算法、AES的RijndaelManaged加密算法,或者也可以采用Base64加密,甚至我看到一个很变态的方式,就是用MD5加密的头,内容则采用Base64的方式加密,一般不知道内情的还真的不好处理。

    在吉日《[走火入魔失眠夜]浅谈管理软件信息安全,用户名、密码的加密解密【附C#配套加密解密源码】》 的文章中也对加密做了一些介绍和分析,并贴出了MD5、DES的加密方式代码,吉日的文章图文并茂、哲理及诙谐例子并存,本文有感而发,做一些补充,希望园子同行共通过切磋,交流心得。

    加密字符串的方式有很多,也都可以通过这样的加密文件内容,不过较好的方式可能是采用DES及AES两种方式来加密文件了,下面贴出的代码中包含了加解密文件的算法。下面具体贴出本人收藏的各种加密算法代码。

    1、DES加密字符串及文件等

    如果想可逆的算法,这种方式一般不错,只要结合动态密钥,就可以做出强度比较高的加密应用了。 

             #region DES对称加密解密

            public const string DEFAULT_ENCRYPT_KEY = "12345678";

            /// <summary>
            /// 使用默认加密
            /// </summary>
            /// <param name="strText"></param>
            /// <returns></returns>
            public static string DesEncrypt(string strText)
            {
                try
                {
                    return DesEncrypt(strText, DEFAULT_ENCRYPT_KEY);
                }
                catch
                {
                    return "";
                }
            }

            /// <summary>
            /// 使用默认解密
            /// </summary>
            /// <param name="strText"></param>
            /// <returns></returns>
            public static string DesDecrypt(string strText)
            {
                try
                {
                    return DesDecrypt(strText, DEFAULT_ENCRYPT_KEY);
                }
                catch
                {
                    return "";
                }
            }

            /// <summary> 
            /// Encrypt the string 
            /// Attention:key must be 8 bits 
            /// </summary> 
            /// <param name="strText">string</param> 
            /// <param name="strEncrKey">key</param> 
            /// <returns></returns> 
            public static string DesEncrypt(string strText, string strEncrKey)
            {
                byte[] byKey = null;
                byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

                byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray = Encoding.UTF8.GetBytes(strText);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return Convert.ToBase64String(ms.ToArray());
            }

            /// <summary> 
            /// Decrypt string 
            /// Attention:key must be 8 bits 
            /// </summary> 
            /// <param name="strText">Decrypt string</param> 
            /// <param name="sDecrKey">key</param> 
            /// <returns>output string</returns> 
            public static string DesDecrypt(string strText, string sDecrKey)
            {
                byte[] byKey = null;
                byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                byte[] inputByteArray = new Byte[strText.Length];

                byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                inputByteArray = Convert.FromBase64String(strText);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                Encoding encoding = new UTF8Encoding();
                return encoding.GetString(ms.ToArray());
            }

            /// <summary> 
            /// Encrypt files 
            /// Attention:key must be 8 bits 
            /// </summary> 
            /// <param name="m_InFilePath">Encrypt file path</param> 
            /// <param name="m_OutFilePath">output file</param> 
            /// <param name="strEncrKey">key</param> 
            public static void DesEncrypt(string m_InFilePath, string m_OutFilePath, string strEncrKey)
            {
                byte[] byKey = null;
                byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

                byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));
                FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);
                FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);
                fout.SetLength(0);
                //Create variables to help with read and write. 
                byte[] bin = new byte[100]; //This is intermediate storage for the encryption. 
                long rdlen = 0; //This is the total number of bytes written. 
                long totlen = fin.Length; //This is the total length of the input file. 
                int len; //This is the number of bytes to be written at a time. 

                DES des = new DESCryptoServiceProvider();
                CryptoStream encStream = new CryptoStream(fout, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);

                //Read from the input file, then encrypt and write to the output file. 
                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }
                encStream.Close();
                fout.Close();
                fin.Close();
            }

            /// <summary> 
            /// Decrypt files 
            /// Attention:key must be 8 bits 
            /// </summary> 
            /// <param name="m_InFilePath">Decrypt filepath</param> 
            /// <param name="m_OutFilePath">output filepath</param> 
            /// <param name="sDecrKey">key</param> 
            public static void DesDecrypt(string m_InFilePath, string m_OutFilePath, string sDecrKey)
            {
                byte[] byKey = null;
                byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

                byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));
                FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);
                FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);
                fout.SetLength(0);
                //Create variables to help with read and write. 
                byte[] bin = new byte[100]; //This is intermediate storage for the encryption. 
                long rdlen = 0; //This is the total number of bytes written. 
                long totlen = fin.Length; //This is the total length of the input file. 
                int len; //This is the number of bytes to be written at a time. 

                DES des = new DESCryptoServiceProvider();
                CryptoStream encStream = new CryptoStream(fout, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);

                //Read from the input file, then encrypt and write to the output file. 
                while (rdlen < totlen)
                {
                    len = fin.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }
                encStream.Close();
                fout.Close();
                fin.Close();
            } 
            #endregion

    2、 对称加密算法AES RijndaelManaged加密解密

             #region 对称加密算法AES RijndaelManaged加密解密

            private static readonly string Default_AES_Key = "@#kim123";
            private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79,
                                                 0x53,0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F };

            /// <summary>
            /// 对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法)
            /// </summary>
            /// <param name="encryptString">待加密字符串</param>
            /// <returns>加密结果字符串</returns>
            public static string AES_Encrypt(string encryptString)
            {
                return AES_Encrypt(encryptString, Default_AES_Key);
            }

            /// <summary>
            /// 对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法)
            /// </summary>
            /// <param name="encryptString">待加密字符串</param>
            /// <param name="encryptKey">加密密钥,须半角字符</param>
            /// <returns>加密结果字符串</returns>
            public static string AES_Encrypt(string encryptString, string encryptKey)
            {
                encryptKey = GetSubString(encryptKey, 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);
            }

            /// <summary>
            /// 对称加密算法AES RijndaelManaged解密字符串
            /// </summary>
            /// <param name="decryptString">待解密的字符串</param>
            /// <returns>解密成功返回解密后的字符串,失败返源串</returns>
            public static string AES_Decrypt(string decryptString)
            {
                return AES_Decrypt(decryptString, Default_AES_Key);
            }

            /// <summary>
            /// 对称加密算法AES RijndaelManaged解密字符串
            /// </summary>
            /// <param name="decryptString">待解密的字符串</param>
            /// <param name="decryptKey">解密密钥,和加密密钥相同</param>
            /// <returns>解密成功返回解密后的字符串,失败返回空</returns>
            public static string AES_Decrypt(string decryptString, string decryptKey)
            {
                try
                {
                    decryptKey = GetSubString(decryptKey, 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 string.Empty;
                }
            }

            /// <summary>
            /// 按字节长度(按字节,一个汉字为2个字节)取得某字符串的一部分
            /// </summary>
            /// <param name="sourceString">源字符串</param>
            /// <param name="length">所取字符串字节长度</param>
            /// <param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,一般为"...")</param>
            /// <returns>某字符串的一部分</returns>
            private static string GetSubString(string sourceString, int length, string tailString)
            {
                return GetSubString(sourceString, 0, length, tailString);
            }

            /// <summary>
            /// 按字节长度(按字节,一个汉字为2个字节)取得某字符串的一部分
            /// </summary>
            /// <param name="sourceString">源字符串</param>
            /// <param name="startIndex">索引位置,以0开始</param>
            /// <param name="length">所取字符串字节长度</param>
            /// <param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,一般为"...")</param>
            /// <returns>某字符串的一部分</returns>
            private static string GetSubString(string sourceString, int startIndex, int length, string tailString)
            {
                string myResult = sourceString;

                //当是日文或韩文时(注:中文的范围:u4e00 - u9fa5, 日文在u0800 - u4e00, 韩文为xAC00-xD7A3)
                if (System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[u0800-u4e00]+") ||
                    System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[xAC00-xD7A3]+"))
                {
                    //当截取的起始位置超出字段串长度时
                    if (startIndex >= sourceString.Length)
                    {
                        return string.Empty;
                    }
                    else
                    {
                        return sourceString.Substring(startIndex,
                                                       ((length + startIndex) > sourceString.Length) ? (sourceString.Length - startIndex) : length);
                    }
                }

                //中文字符,如"中国人民abcd123"
                if (length <= 0)
                {
                    return string.Empty;
                }
                byte[] bytesSource = Encoding.Default.GetBytes(sourceString);

                //当字符串长度大于起始位置
                if (bytesSource.Length > startIndex)
                {
                    int endIndex = bytesSource.Length;

                    //当要截取的长度在字符串的有效长度范围内
                    if (bytesSource.Length > (startIndex + length))
                    {
                        endIndex = length + startIndex;
                    }
                    else
                    {   //当不在有效范围内时,只取到字符串的结尾
                        length = bytesSource.Length - startIndex;
                        tailString = "";
                    }

                    int[] anResultFlag = new int[length];
                    int nFlag = 0;
                    //字节大于127为双字节字符
                    for (int i = startIndex; i < endIndex; i++)
                    {
                        if (bytesSource[i] > 127)
                        {
                            nFlag++;
                            if (nFlag == 3)
                            {
                                nFlag = 1;
                            }
                        }
                        else
                        {
                            nFlag = 0;
                        }
                        anResultFlag[i] = nFlag;
                    }
                    //最后一个字节为双字节字符的一半
                    if ((bytesSource[endIndex - 1] > 127) && (anResultFlag[length - 1] == 1))
                    {
                        length = length + 1;
                    }

                    byte[] bsResult = new byte[length];
                    Array.Copy(bytesSource, startIndex, bsResult, 0, length);
                    myResult = Encoding.Default.GetString(bsResult);
                    myResult = myResult + tailString;

                    return myResult;
                }

                return string.Empty;

            }

            /// <summary>
            /// 加密文件流
            /// </summary>
            /// <param name="fs"></param>
            /// <returns></returns>
            public static CryptoStream AES_EncryptStrream(FileStream fs, string decryptKey)
            {
                decryptKey = GetSubString(decryptKey, 32, "");
                decryptKey = decryptKey.PadRight(32, ' ');

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

                ICryptoTransform encrypto = rijndaelProvider.CreateEncryptor();
                CryptoStream cytptostreamEncr = new CryptoStream(fs, encrypto, CryptoStreamMode.Write);
                return cytptostreamEncr;
            }

            /// <summary>
            /// 解密文件流
            /// </summary>
            /// <param name="fs"></param>
            /// <returns></returns>
            public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey)
            {
                decryptKey = GetSubString(decryptKey, 32, "");
                decryptKey = decryptKey.PadRight(32, ' ');

                RijndaelManaged rijndaelProvider = new RijndaelManaged();
                rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);
                rijndaelProvider.IV = Keys;
                ICryptoTransform Decrypto = rijndaelProvider.CreateDecryptor();
                CryptoStream cytptostreamDecr = new CryptoStream(fs, Decrypto, CryptoStreamMode.Read);
                return cytptostreamDecr;
            }

            /// <summary>
            /// 对指定文件加密
            /// </summary>
            /// <param name="InputFile"></param>
            /// <param name="OutputFile"></param>
            /// <returns></returns>
            public static bool AES_EncryptFile(string InputFile, string OutputFile)
            {
                try
                {
                    string decryptKey = "www.iqidi.com";

                    FileStream fr = new FileStream(InputFile, FileMode.Open);
                    FileStream fren = new FileStream(OutputFile, FileMode.Create);
                    CryptoStream Enfr = AES_EncryptStrream(fren, decryptKey);
                    byte[] bytearrayinput = new byte[fr.Length];
                    fr.Read(bytearrayinput, 0, bytearrayinput.Length);
                    Enfr.Write(bytearrayinput, 0, bytearrayinput.Length);
                    Enfr.Close();
                    fr.Close();
                    fren.Close();
                }
                catch
                {
                    //文件异常
                    return false;
                }
                return true;
            }

            /// <summary>
            /// 对指定的文件解压缩
            /// </summary>
            /// <param name="InputFile"></param>
            /// <param name="OutputFile"></param>
            /// <returns></returns>
            public static bool AES_DecryptFile(string InputFile, string OutputFile)
            {
                try
                {
                    string decryptKey = "www.iqidi.com";
                    FileStream fr = new FileStream(InputFile, FileMode.Open);
                    FileStream frde = new FileStream(OutputFile, FileMode.Create);
                    CryptoStream Defr = AES_DecryptStream(fr, decryptKey);
                    byte[] bytearrayoutput = new byte[1024];
                    int m_count = 0;

                    do
                    {
                        m_count = Defr.Read(bytearrayoutput, 0, bytearrayoutput.Length);
                        frde.Write(bytearrayoutput, 0, m_count);
                        if (m_count < bytearrayoutput.Length)
                            break;
                    } while (true);

                    Defr.Close();
                    fr.Close();
                    frde.Close();
                }
                catch
                {
                    //文件异常
                    return false;
                }
                return true;
            }
            
            #endregion

    3、  Base64加密解密算法

             #region Base64加密解密

            /// <summary>
            /// Base64是一種使用64基的位置計數法。它使用2的最大次方來代表僅可列印的ASCII 字元。
            /// 這使它可用來作為電子郵件的傳輸編碼。在Base64中的變數使用字元A-Z、a-z和0-9 ,
            /// 這樣共有62個字元,用來作為開始的64個數字,最後兩個用來作為數字的符號在不同的
            /// 系統中而不同。
            /// Base64加密
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            public static string Base64Encrypt(string str)
            {
                byte[] encbuff = System.Text.Encoding.UTF8.GetBytes(str);
                return Convert.ToBase64String(encbuff);
            }

            /// <summary>
            /// Base64解密
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            public static string Base64Decrypt(string str)
            {
                byte[] decbuff = Convert.FromBase64String(str);
                return System.Text.Encoding.UTF8.GetString(decbuff);
            } 
            #endregion

    4、 MD5加密及验证

    MD5的加密处理应用还是比较多,由于破解难度很大,基本上大型网站或者软件商,密码加密一般采用这种方式居多。

    而MD5可以用来获得32、 16、8等全部部分内容加密内容,也可以获取其加密后的哈希值。

             /// <summary>

            /// 获得32位的MD5加密
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string GetMD5_32(string input)
            {
                System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
                byte[] data = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(input));
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sb.Append(data[i].ToString("x2"));
                }
                return sb.ToString();
            }

            /// <summary>
            /// 获得16位的MD5加密
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string GetMD5_16(string input)
            {
                return GetMD5_32(input).Substring(8, 16);
            }
            /// <summary>
            /// 获得8位的MD5加密
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string GetMD5_8(string input)
            {
                return GetMD5_32(input).Substring(8, 8);
            }
            /// <summary>
            /// 获得4位的MD5加密
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string GetMD5_4(string input)
            {
                return GetMD5_32(input).Substring(8, 4);
            }

            public static string MD5EncryptHash(String input)
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                //the GetBytes method returns byte array equavalent of a string
                byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);
                char[] temp = new char[res.Length];
                //copy to a char array which can be passed to a String constructor
                Array.Copy(res, temp, res.Length);
                //return the result as a string
                return new String(temp);
            }

    5、 对文件添加MD5标签及验证

    这种方式比较有趣,我也是最近才发现其中的奥妙,其实我们为了防止文件被修改,可以采用这种方式预先添加MD5码,然后在程序代码中进行验证,这样至少可以减少部分篡改的行为吧,因为只要文件有些少的修改,Md5码将会发生变化的,呵呵。

             #region MD5签名验证

            /// <summary>
            /// 对给定文件路径的文件加上标签
            /// </summary>
            /// <param name="path">要加密的文件的路径</param>
            /// <returns>标签的值</returns>
            public static bool AddMD5(string path)
            {
                bool IsNeed = true;

                if (CheckMD5(path))                                  //已进行MD5处理
                    IsNeed = false;

                try
                {
                    FileStream fsread = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                    byte[] md5File = new byte[fsread.Length];
                    fsread.Read(md5File, 0, (int)fsread.Length);                               // 将文件流读取到Buffer中
                    fsread.Close();

                    if (IsNeed)
                    {
                        string result = MD5Buffer(md5File, 0, md5File.Length);             // 对Buffer中的字节内容算MD5
                        byte[] md5 = System.Text.Encoding.ASCII.GetBytes(result);       // 将字符串转换成字节数组以便写人到文件中
                        FileStream fsWrite = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
                        fsWrite.Write(md5File, 0, md5File.Length);                               // 将文件,MD5值 重新写入到文件中。
                        fsWrite.Write(md5, 0, md5.Length);
                        fsWrite.Close();
                    }
                    else
                    {
                        FileStream fsWrite = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
                        fsWrite.Write(md5File, 0, md5File.Length);
                        fsWrite.Close();
                    }
                }
                catch
                {
                    return false;
                }

                return true;
            }

            /// <summary>
            /// 对给定路径的文件进行验证
            /// </summary>
            /// <param name="path"></param>
            /// <returns>是否加了标签或是否标签值与内容值一致</returns>
            public static bool CheckMD5(string path)
            {
                try
                {
                    FileStream get_file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
                    byte[] md5File = new byte[get_file.Length];                                      // 读入文件
                    get_file.Read(md5File, 0, (int)get_file.Length);
                    get_file.Close();

                    string result = MD5Buffer(md5File, 0, md5File.Length - 32);             // 对文件除最后32位以外的字节计算MD5,这个32是因为标签位为32位。
                    string md5 = System.Text.Encoding.ASCII.GetString(md5File, md5File.Length - 32, 32);   //读取文件最后32位,其中保存的就是MD5值
                    return result == md5;
                }
                catch
                {
                    return false;
                }
            }

            /// <summary>
            /// 计算文件的MD5值
            /// </summary>
            /// <param name="MD5File">MD5签名文件字符数组</param>
            /// <param name="index">计算起始位置</param>
            /// <param name="count">计算终止位置</param>
            /// <returns>计算结果</returns>
            private static string MD5Buffer(byte[] MD5File, int index, int count)
            {
                System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] hash_byte = get_md5.ComputeHash(MD5File, index, count);
                string result = System.BitConverter.ToString(hash_byte);

                result = result.Replace("-", "");
                return result;
            } 
            #endregion

    6、 SHA256加密算法

             /// <summary>

            /// SHA256函数
            /// </summary>
            /// <param name="str">原始字符串</param>
            /// <returns>SHA256结果(返回长度为44字节的字符串)</returns>
            public static string SHA256(string str)
            {
                byte[] SHA256Data = Encoding.UTF8.GetBytes(str);
                SHA256Managed Sha256 = new SHA256Managed();
                byte[] Result = Sha256.ComputeHash(SHA256Data);
                return Convert.ToBase64String(Result);  //返回长度为44字节的字符串
            }

    7、 MD5及Base64结合加密

    这种结合方式也是比较不错的算法,至少是四不像,一般分析比较困难,比较有迷惑性,就是挂羊头,卖狗肉的行为,其实Base64加密方式,也可以做的比较复杂,不一定是上面的那种解决方式的,你可以添加一些较为复杂的算法在里面的。 

             /// <summary>

            /// 加密字符串
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string EncryptString(string input)
            {
                return MD5Util.AddMD5Profix(Base64Util.Encrypt(MD5Util.AddMD5Profix(input)));
                //return Base64.Encrypt(MD5.AddMD5Profix(Base64.Encrypt(input)));
            }

            /// <summary>
            /// 解密加过密的字符串
            /// </summary>
            /// <param name="input"></param>
            /// <param name="throwException">解密失败是否抛异常</param>
            /// <returns></returns>
            public static string DecryptString(string input, bool throwException)
            {
                string res = "";
                try
                {
                    res = input;// Base64.Decrypt(input);
                    if (MD5Util.ValidateValue(res))
                    {
                        return MD5Util.RemoveMD5Profix(Base64Util.Decrypt(MD5Util.RemoveMD5Profix(res)));
                    }
                    else
                    {
                        throw new Exception("字符串无法转换成功!");
                    }
                }
                catch
                {
                    if (throwException)
                    {
                        throw;
                    }
                    else
                    {
                        return "";
                    }
                }
            }

    //-----------下面是MD5Util下面的函数

            /// <summary>
            /// 添加MD5的前缀,便于检查有无篡改
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string AddMD5Profix(string input)
            {
                return GetMD5_4(input) + input;
            }
            /// <summary>
            /// 移除MD5的前缀
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string RemoveMD5Profix(string input)
            {
                return input.Substring(4);
            }
            /// <summary>
            /// 验证MD5前缀处理的字符串有无被篡改
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static bool ValidateValue(string input)
            {
                bool res = false;
                if (input.Length >= 4)
                {
                    string tmp = input.Substring(4);
                    if (input.Substring(0, 4) == GetMD5_4(tmp))
                    {
                        res = true;
                    }
                }
                return res;
            }

     如下面代码就是上面提到的Base64Util中的内容,好像算法处理还是比较麻烦,也贴出来大家研读一下吧。

        /// <summary>
        /// 基于Base64的加密编码,
        /// 可以设置不同的密码表来获取不同的编码合解码
        /// </summary>
        public class Base64Util
        {
            public Base64Util()
            {
                this.InitDict();
            }

            protected static Base64Util s_b64 = new Base64Util();

            /// <summary>
            /// 使用默认的密码表加密字符串
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string Encrypt(string input)
            {
                return s_b64.Encode(input);
            }
            /// <summary>
            /// 使用默认的密码表解密字符串
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string Decrypt(string input)
            {
                return s_b64.Decode(input);
            }

            /// <summary>
            /// 获取具有标准的Base64密码表的加密类
            /// </summary>
            /// <returns></returns>
            public static Base64Util GetStandardBase64()
            {
                Base64Util b64 = new Base64Util();
                b64.Pad = "=";
                b64.CodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                return b64;
            }

            protected string m_codeTable = @"ABCDEFGHIJKLMNOPQRSTUVWXYZbacdefghijklmnopqrstu_wxyz0123456789*-";
            protected string m_pad = "v";
            protected Dictionary<int, char> m_t1 = new Dictionary<int, char>();
            protected Dictionary<char, int> m_t2 = new Dictionary<char, int>();

            /// <summary>
            /// 密码表
            /// </summary>
            public string CodeTable
            {
                get { return m_codeTable; }
                set
                {
                    if (value == null)
                    {
                        throw new Exception("密码表不能为null");
                    }
                    else if (value.Length < 64)
                    {
                        throw new Exception("密码表长度必须至少为64");
                    }
                    else
                    {
                        this.ValidateRepeat(value);
                        this.ValidateEqualPad(value, m_pad);
                        m_codeTable = value;
                        this.InitDict();
                    }
                }
            }
            /// <summary>
            /// 补码
            /// </summary>
            public string Pad
            {
                get { return m_pad; }
                set
                {
                    if (value == null)
                    {
                        throw new Exception("密码表的补码不能为null");
                    }
                    else if (value.Length != 1)
                    {
                        throw new Exception("密码表的补码长度必须为1");
                    }
                    else
                    {
                        this.ValidateEqualPad(m_codeTable, value);
                        m_pad = value;
                        this.InitDict();
                    }
                }
            }


            /// <summary>
            /// 返回编码后的字符串
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            public string Encode(string source)
            {
                if (source == null || source == "")
                {
                    return "";
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    byte[] tmp = System.Text.UTF8Encoding.UTF8.GetBytes(source);
                    int remain = tmp.Length % 3;
                    int patch = 3 - remain;
                    if (remain != 0)
                    {
                        Array.Resize(ref tmp, tmp.Length + patch);
                    }
                    int cnt = (int)Math.Ceiling(tmp.Length * 1.0 / 3);
                    for (int i = 0; i < cnt; i++)
                    {
                        sb.Append(this.EncodeUnit(tmp[i * 3], tmp[i * 3 + 1], tmp[i * 3 + 2]));
                    }
                    if (remain != 0)
                    {
                        sb.Remove(sb.Length - patch, patch);
                        for (int i = 0; i < patch; i++)
                        {
                            sb.Append(m_pad);
                        }
                    }
                    return sb.ToString();
                }

            }
            protected string EncodeUnit(params byte[] unit)
            {
                int[] obj = new int[4];
                obj[0] = (unit[0] & 0xfc) >> 2;
                obj[1] = ((unit[0] & 0x03) << 4) + ((unit[1] & 0xf0) >> 4);
                obj[2] = ((unit[1] & 0x0f) << 2) + ((unit[2] & 0xc0) >> 6);
                obj[3] = unit[2] & 0x3f;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < obj.Length; i++)
                {
                    sb.Append(this.GetEC((int)obj[i]));
                }
                return sb.ToString();
            }
            protected char GetEC(int code)
            {
                return m_t1[code];//m_codeTable[code];
            }

            /// <summary>
            /// 获得解码字符串
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            public string Decode(string source)
            {
                if (source == null || source == "")
                {
                    return "";
                }
                else
                {
                    List<byte> list = new List<byte>();
                    char[] tmp = source.ToCharArray();
                    int remain = tmp.Length % 4;
                    if (remain != 0)
                    {
                        Array.Resize(ref tmp, tmp.Length - remain);
                    }
                    int patch = source.IndexOf(m_pad);
                    if (patch != -1)
                    {
                        patch = source.Length - patch;
                    }
                    int cnt = tmp.Length / 4;
                    for (int i = 0; i < cnt; i++)
                    {
                        this.DecodeUnit(list, tmp[i * 4], tmp[i * 4 + 1], tmp[i * 4 + 2], tmp[i * 4 + 3]);
                    }
                    for (int i = 0; i < patch; i++)
                    {
                        list.RemoveAt(list.Count - 1);
                    }
                    return System.Text.Encoding.UTF8.GetString(list.ToArray());
                }
            }
            protected void DecodeUnit(List<byte> byteArr, params char[] chArray)
            {
                int[] res = new int[3];
                byte[] unit = new byte[chArray.Length];
                for (int i = 0; i < chArray.Length; i++)
                {
                    unit[i] = this.FindChar(chArray[i]);
                }
                res[0] = (unit[0] << 2) + ((unit[1] & 0x30) >> 4);
                res[1] = ((unit[1] & 0xf) << 4) + ((unit[2] & 0x3c) >> 2);
                res[2] = ((unit[2] & 0x3) << 6) + unit[3];
                for (int i = 0; i < res.Length; i++)
                {
                    byteArr.Add((byte)res[i]);
                }
            }
            protected byte FindChar(char ch)
            {
                int pos = m_t2[ch];//m_codeTable.IndexOf(ch);
                return (byte)pos;
            }

            /// <summary>
            /// 初始化双向哈西字典
            /// </summary>
            protected void InitDict()
            {
                m_t1.Clear();
                m_t2.Clear();
                m_t2.Add(m_pad[0], -1);
                for (int i = 0; i < m_codeTable.Length; i++)
                {
                    m_t1.Add(i, m_codeTable[i]);
                    m_t2.Add(m_codeTable[i], i);
                }
            }
            /// <summary>
            /// 检查字符串中的字符是否有重复
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            protected void ValidateRepeat(string input)
            {
                for (int i = 0; i < input.Length; i++)
                {
                    if (input.LastIndexOf(input[i]) > i)
                    {
                        throw new Exception("密码表中含有重复字符:" + input[i]);
                    }
                }
            }
            /// <summary>
            /// 检查字符串是否包含补码字符
            /// </summary>
            /// <param name="input"></param>
            /// <param name="pad"></param>
            protected void ValidateEqualPad(string input, string pad)
            {
                if (input.IndexOf(pad) > -1)
                {
                    throw new Exception("密码表中包含了补码字符:" + pad);
                }
            }
        }
  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/lppblogs/p/4023705.html
Copyright © 2011-2022 走看看