谈谈数据加密的处理--提供各种算法处理

长平狐 发布于 2012/06/11 17:29
阅读 239
收藏 1

数据的加密重要性大家皆知,很多情况下需要对数据进行加密处理,但各种重要数据的加密要求不一样,有些需要时可逆的,有些是不要求可逆的,可逆的一般称之为对称加密算法,不可逆的一般可以成为非对称加密算法。如登录密码,一般较好的方式是采用不可逆的加密算法,如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.RegularExssions.Regex.IsMatch(sourceString,  " [\u0800-\u4e00]+ " ||
                System.Text.RegularExssions.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);
            }
        }

    }

 

 

 

 

 

 

 

 


原文链接:http://www.cnblogs.com/wuhuacong/archive/2010/09/30/1839119.html
加载中
返回顶部
顶部