1. 程式人生 > >以鹿為馬-從凱撒到MD5

以鹿為馬-從凱撒到MD5

如果說驗證碼講究的是實事求是,那麼密碼用以鹿為馬來形容似乎也頗為恰當。你看到的永遠只是我讓你看到的,你想知道的是我永遠不想讓你知道的,於是密碼與密碼的破譯便像一對雙胞胎一樣誕生了,其實它更像是一面單向玻璃的正反兩面,緊緊貼在一起,卻始終對對方是一副模糊的面孔。
初次認識到密碼這個東西是從電視劇《暗算》開始的,不過藝術性處理過於嚴重,難免讓人覺得有點玄乎。在後來關於密碼的影視作品就是講述計算機之父圖靈的《模仿遊戲》,這個片名可謂絕妙,密碼與密碼的破譯不正是互相進行模仿的遊戲嗎。只是有人更善於偽裝而已。
密碼的出現歷史久遠,比如著名的凱撒密碼,為了防止敵方截獲情報,凱撒於是創立了最原始的密碼。原理也很簡單,凱撒把羅馬字母建立了一張對一個的字母表,於是每個原來的字母變成了對應的其他字母,此時若沒有密碼本,即使得到了資訊也看不懂。用變成實現凱撒密碼非常簡單,即把原來字元的ASCII碼進行約定號的偏移即可將原文加密,其c#程式碼如下:
 public string caesar(string strpwd)
        {
            char[] c = strpwd.ToCharArray();
            string strcaesar = "";//用來儲存加密後的字串
            for (int i = 0; i < strpwd.Length; i++)
            {
                string ins = c[i].ToString();
                string outs = "";
                //判斷字串元素是否包含
bool ischar = "0123456789qazwsxedcrfvtgbyhnujmikolp".Contains(ins.ToLower()); bool isupper = ischar && (ins.ToUpper() == ins); ins = ins.ToLower(); if (ischar) { byte[] array = System.Text.Encoding.
ASCII.GetBytes(ins); for (int j = 0; j < array.Length; j++) { int offset = (int)(array[j]); outs = Convert.ToChar(offset + 5).ToString(); } if (isupper) { outs = outs.ToUpper(); } } else { outs = ins; } strcaesar += outs; } return strcaesar; }

這裡用到了string類中的ToCharArray方法將字串賦值到Unicode陣列。
但不難看出,凱撒密碼雖然算得上一個密碼,但只要多截獲一些情報進行頻率分析,還是可以比較容易的破解密碼。在很長一段時間中,加密傳遞資訊僅僅是依靠這類經驗性的加密方法,沒有意識到應用數學原理進行加密,當然隨著今天資訊理論的完善,密碼學已經成為一門以數學為基礎的學問(簡單入門可以去看吳軍先生的《數學之美》一書)。下面介紹一種今天常用於驗證登陸密碼的加密演算法-MD5.
MD5-訊息照耀演算法,是一種密碼雜湊函式,它以512位分組來處理輸入的資訊,且每一分組又被劃分為16個32位子分組,經過這一系列處理,演算法輸出有4個32位分組級聯後生成一個128位雜湊值。下面用c#程式碼來實現一個MD5加密演算法:

 public string md5creat(string strpwd)
        {
            string cc = DateTime.Now.Month + strpwd + DateTime.Now.Minute;
            string pwd = "";
            MD5 md5 = MD5.Create();
            //兩種將字串轉換為md5碼方法
           /* byte[] b = System.Text.Encoding.Default.GetBytes(cc);
            byte[] md5data = md5.ComputeHash(b);*/
            byte[] md5data = md5.ComputeHash(Encoding.UTF8.GetBytes(cc));
            md5data.Reverse();
            for(int i=3;i<md5data.Length;i++)//不從第一位開始,增加加密難度
            {
                pwd+=md5data[i].ToString("x").PadLeft(2,'0');
            }
            return pwd;
        }