天天看點

一個不錯的加密算法

一個很不錯的加密算法,C#語言編寫

算法加密特點:每次加密的結果都不同,但解密的結果都相同,而且都是加密後的資料:

--加密算法:sSource是加密的字元竄  

--int iFlag=1是加密  2是解密  

public static string pWord(string sSource,int iFlag)  

  {  

   if(sSource==null)  

    return null;  

   if(sSource.Equals(""))  

    return "";  

   int li_len,i,li_asc,li_rand,li_head;  

            string ls_i,ls_code="";  

   if(iFlag ==1)  

   {  

    li_len=sSource.Length;  

    Random rdm1 = new Random(~unchecked((int)DateTime.Now.Ticks));   

    li_head=(int)(rdm1.NextDouble()*10);  

    if(li_head ==0)  

     li_head =1;  

    for(i=0; i<li_len; i++)  

    {  

     Random rdm2 = new Random(~unchecked((int)DateTime.Now.Ticks));   

     int rand2 =(int)(rdm2.NextDouble() *94);  

     if(rand2 ==0)  

      rand2 =1;  

     li_rand=rand2+32;  

     li_asc=Convert.ToInt32(sSource.ToCharArray(i,1)[0]);  

     ls_i=((char)(li_asc -i)).ToString();  

     if(li_asc+i+li_head>126)  

     {  

      if(li_rand%2 ==1)  

       li_rand=li_rand+1;  

      ls_i=((char)(li_rand)).ToString()+((char)(li_asc -i -li_head)).ToString();  

     }  

     else 

      if(li_rand%2 ==0)   

      ls_i=((char)(li_rand)).ToString()+((char)(li_asc +i +li_head)).ToString();  

     ls_code=ls_code+ls_i;  

    }  

    Random rdm3 = new Random(~unchecked((int)DateTime.Now.Ticks));   

    int rand1 =(int)(rdm3.NextDouble()*9);  

    if(rand1 ==0)  

     rand1 =1;  

    ls_code=((char)(rand1*10+li_head+40)).ToString()+ls_code;  

   }  

   else 

    int li_ret;  

    ls_code="";  

    li_ret=Convert.ToInt32(sSource.ToCharArray(0,1)[0]) %10;  

    for( i=2;i <li_len; i=i+2)  

     if(Convert.ToInt32(sSource.ToCharArray(i - 1,1)[0]) %2 ==0)  

      ls_i=((char)(li_asc + (i - 1)/2 + li_ret)).ToString();  

      ls_i=((char)(li_asc - (i - 1)/2 - li_ret)).ToString();  

   return ls_code;  

  } 

對于該加密算法的使用方法:

該加密算法的特點是無論加密多少次但每次解密的結果都是一緻的,有個缺點是每次無論加密和解密都需要明文,目前我們對使用者登陸的使用者名和密碼進行加密來驗證使用者身份:

在Username中輸入使用者名(密碼簡化主要示範這個算法的用法),當點選加密時顯示加密和解密後的資料,

第一次加密結果:

第二次加密結果:

從上面可以看出加密都是相同的資料chenkai,顯示的加密結果不同,但解密的資料始終相同。

--Author:chenkai  Time:2009年3月3日14:33:40  

--Button1點選加密的觸發事件方法  

protected void Button1_Click(object sender, EventArgs e)  

        //獲得加密資料  

        string EncrytString = this.TextBox1.Text;  

        //進行加密  

        this.TextBox2.Text=pWord(EncrytString, 1);  

        //進行解密  

        this.TextBox3.Text = pWord(EncrytString, 2);  

--從上面看出加密和解密傳入的是EncrytString(chenkai),既都需要明文傳入 

當使用者登陸時需要向伺服器端傳入資料和資料庫進行比對,為了保證資料傳輸的安全性對明文資料進行該算法加密,相對而言資料庫如何設計?

如果我們資料庫中儲存的是加密後的資料,這樣的話因為每次使用者登陸加密的結果都不相同,雖然保證資料安全但無法驗證使用者的身份。這種方案行不通

在則資料庫中儲存的是解密的資料,我們在使用者注冊時把使用者登陸的使用者名進行解密處理并存入資料庫,根據該算法特點無論怎麼加密而解密結果始終是一至的,那麼使用者在注冊後多次登陸中對使用者名進行解密并與資料庫進行比對,來判斷使用者身份,這種方案似乎能夠行得通。但這點恰恰就暴露這個算法的缺點,解密時需要明文,那麼從用戶端傳來的是加密後的資料而非明文,這種方案也沒有用 。該如何更好利用該算法呢?

我們可以這樣設計資料庫來利用該算法:

在資料庫中存入的是明文,那麼當使用者登陸時有兩種資料加密和解密 都是非明文,如何選擇呢?上面的兩種方法都選擇是加密資料,死胡同一條,如果我們換一個角度換成解密資料傳輸到伺服器端于資料庫進行比對,而資料庫存儲的是明文對它進行解密處理,再同用戶端傳來的使用者登陸解密資料進行比對來判斷使用者身份,在傳輸中是非明文而且還能驗證用戶端使用者身份,這種方案能夠行得通。

呵呵繞了大半天,當然這個算法設計不太好(不是很實用),但如果想用到還是有辦法的。

本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/765468