隨筆-128  評論-55  文章-5  trackbacks-0
           

          SHA-1算法簡介及JavaScript實現(xiàn)

          一、SHA-1算法簡介

          消息認證作為一種重要的安全技術(shù)如今已被廣泛地應(yīng)用于網(wǎng)絡(luò)信息交換領(lǐng)域,它的根本作用是允許通信的當事人驗證所接受的消息為可信消息。如果消息、文件、文檔或者其他的數(shù)據(jù)集合是真實的數(shù)據(jù)并且來自所聲稱的數(shù)據(jù)源,那么稱這些數(shù)據(jù)集合是可信的。而在消息認證技術(shù)中通常都會用到一類特殊的數(shù)學算法-哈希算法,它占有極其重要的地位。哈希算法也即散列算法,其作用是對任何不定長的比特串(稱為消息)計算出一個定長的比特串(稱為消息摘要或散列值)
              目前常見的哈希算法有MD5SHA-1RIPEMD-160,而國內(nèi)更傾向于MD5SHA-1。就當前的情況來看,SHA-1由于其安全強度及運算效率方面的優(yōu)勢已經(jīng)成為使用最為廣泛的哈希算法了。

          1.1 SHA-1算法概述

          SHA-1算法由美國國家標準和技術(shù)協(xié)會(NIST)與美國國家安全局(NSA)設(shè)計,并且被美國政府采納,成為美國國家標準。事實上SHA-1目前是全世界使用最為廣泛的哈希算法,已經(jīng)成為業(yè)界的事實標準。可以對長度不超過2^64比特的消息進行計算,輸入以512位數(shù)據(jù)塊為單位處理,產(chǎn)生160比特的消息摘要作為輸出。該算法的處理流程大致分為5個步驟:

          l        步驟1:附加填充比特。

          對輸入的數(shù)據(jù)進行填充,使得數(shù)據(jù)位長度對512求余的結(jié)果為448。填充比特串的最高位補一個1,其余位補0。附加填充總是要進行的,即使消息的長度滿足所要求的長度。

          l        步驟2附加長度值。

          64比特加在報文后表示報文的原始長度,使報文長度為512比特的倍數(shù)。

          l        步驟3:初始化MD緩存。

          一個160MD緩沖區(qū)用以保存中間和最終散列函數(shù)的結(jié)果。它可以表示為532位的寄存器(A,B,C,D,E)。初始化為:

          A = 67452301    B = EFCDAB89    C = 98BADCFE

          D = 10325476    E = C3D2E1F0

          前四個與MD5相同,但存儲為big-endian format

          l        步驟4512比特(16個字)分組處理消息。

          此算法的核心就是稱為壓縮函數(shù)compression function)的模塊,這個模塊包括4次循環(huán),每次循環(huán)又包含20個處理步驟。4次循環(huán)具有相似的結(jié)構(gòu),但每次循環(huán)使用不同的基本邏輯函數(shù),稱為 f1,f2,f3,f4。






          二、SHA-1算法的程序?qū)崿F(xiàn)

          算法采用JavaScript實現(xiàn),JavaScript是一種流行的腳本語言,它是在瀏覽器中解釋執(zhí)行的,因此不需要編譯。整個程序的形式是一個HTML網(wǎng)頁文件,當打開此網(wǎng)頁時,程序會在瀏覽器中解釋執(zhí)行。(部分參照網(wǎng)絡(luò)源代碼)

          2.1 算法程序結(jié)構(gòu)

          整個程序由9個函數(shù)組成,分別介紹如下:

          l         function hex_sha1(s)

          主函數(shù)根據(jù)輸入的消息字符串計算消息摘要,返回十六進制表示的消息摘要。 

          l         function core_sha1(blockArray)

          計算消息摘要的核心函數(shù),輸入為已經(jīng)附加填充位和附加長度值的消息。以數(shù)值數(shù)組表示,數(shù)組中的每一項均為32bit表示的數(shù)值。輸出為長度為5的數(shù)值數(shù)組,對應(yīng)160位的消息摘要。 

          l         function AlignSHA1(str)

          對消息進行附加填充位和附加長度。輸入為消息字符串,輸出為已經(jīng)附加填充位和附加長度值的消息。 

          l         function sha1_ft(t, b, c, d)

          根據(jù)t值返回相應(yīng)得壓縮函數(shù)中用到的f函數(shù)。 

          l         function sha1_kt(t)

          根據(jù)t值返回相應(yīng)得壓縮函數(shù)中用到的K值。

          l         function safe_add(x, y)

          對輸入的兩個32位數(shù)值進行 mod  的加法。 

          l         function rol(num, cnt)

          對輸入的32位的num二進制數(shù)進行循環(huán)左移。

          l         function binb2hex(binarray)

          將輸入的二進制數(shù)組轉(zhuǎn)化為十六進制的字符串。

          l         function calcDigest()

          根據(jù)用戶輸入的源消息計算消息摘要,JavaScript事件函數(shù)。

           

          2.1 程序運行結(jié)果

                 用瀏覽器打開HTML頁面,輸入源消息字符串,點擊計算按鈕即可獲得消息摘要,截圖如下(圖2.1):

          2.1  SHA-1程序運行結(jié)果

           

           

          三、附件(SHA1算法程序源代碼)

          文件SHA1Test.html

           

          <html>

                 
          <head>

                        
          <script language="JavaScript">

          /*

           * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS PUB 180-1

           * By lizq

           * 2006-11-11

           
          */


          /*

           * Configurable variables.

           
          */


          var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */

          var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

           

          /*

           * The main function to calculate message digest

           
          */


          function hex_sha1(s)

          {

                 
          return binb2hex(core_sha1(AlignSHA1(s)));

          }


           

           

          /*

           * Perform a simple self-test to see if the VM is working

           
          */


          function sha1_vm_test()

          {

            
          return hex_sha1("abc"== "a9993e364706816aba3e25717850c26c9cd0d89d";

          }


           

           

          /*

           * Calculate the SHA-1 of an array of big-endian words, and a bit length

           
          */


          function core_sha1(blockArray)

          {

            
          var x = blockArray;  //append padding

           

            
          var w = Array(80);

            
          var a =  1732584193;

            
          var b = -271733879;

            
          var c = -1732584194;

            
          var d =  271733878;

            
          var e = -1009589776;

           

            
          for(var i = 0; i < x.length; i += 16)  //每次處理512位 16*32

            
          {

              
          var olda = a;

              
          var oldb = b;

              
          var oldc = c;

              
          var oldd = d;

              
          var olde = e;

           

              
          for(var j = 0; j < 80; j++)  //對每個512位進行80步操作

              
          {

                
          if(j < 16) w[j] = x[i + j];

                
          else w[j] = rol(w[j-3^ w[j-8^ w[j-14^ w[j-16], 1);

                

                
          var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),

                                 safe_add(safe_add(e, w[j]), sha1_kt(j)));

                e 
          = d;

                d 
          = c;

                c 
          = rol(b, 30);

                b 
          = a;

                a 
          = t;

              }


           

              a 
          = safe_add(a, olda);

              b 
          = safe_add(b, oldb);

              c 
          = safe_add(c, oldc);

              d 
          = safe_add(d, oldd);

              e 
          = safe_add(e, olde);

            }


            
          return new Array(a, b, c, d, e);

           

          }


           

           

          /*

           * Perform the appropriate triplet combination function for the current iteration

           * 返回對應(yīng)F函數(shù)的值

           
          */


          function sha1_ft(t, b, c, d)

          {

            
          if(t < 20return (b & c) | ((~b) & d);

            
          if(t < 40return b ^ c ^ d;

            
          if(t < 60return (b & c) | (b & d) | (c & d);

            
          return b ^ c ^ d;  //t<80

          }


           

           

          /*

           * Determine the appropriate additive constant for the current iteration

           * 返回對應(yīng)的Kt值

           
          */


          function sha1_kt(t)

          {

            
          return (t < 20?  1518500249 : (t < 40?  1859775393 :

                   (t 
          < 60? -1894007588 : -899497514;

          }


           

           

          /*

           * Add integers, wrapping at 2^32. This uses 16-bit operations internally

           * to work around bugs in some JS interpreters.

           * 將32位數(shù)拆成高16位和低16位分別進行相加,從而實現(xiàn) MOD 2^32 的加法

           
          */


          function safe_add(x, y)

          {

            
          var lsw = (x & 0xFFFF+ (y & 0xFFFF);

            
          var msw = (x >> 16+ (y >> 16+ (lsw >> 16);

            
          return (msw << 16| (lsw & 0xFFFF);

          }


           

           

          /*

           * Bitwise rotate a 32-bit number to the left.

           * 32位二進制數(shù)循環(huán)左移

           
          */


          function rol(num, cnt)

          {

            
          return (num << cnt) | (num >>> (32 - cnt));

          }


           

           

          /*

           * The standard SHA1 needs the input string to fit into a block

           * This function align the input string to meet the requirement

           
          */


          function AlignSHA1(str){

            
          var nblk=((str.length+8)>>6)+1, blks=new Array(nblk*16);

            
          for(var i=0;i<nblk*16;i++)blks[i]=0;

            
          for(i=0;i<str.length;i++)

              blks[i
          >>2]|=str.charCodeAt(i)<<(24-(i&3)*8);

            blks[i
          >>2]|=0x80<<(24-(i&3)*8);

            blks[nblk
          *16-1]=str.length*8;

            
          return blks;

          }


           

           

          /*

           * Convert an array of big-endian words to a hex string.

           
          */


          function binb2hex(binarray)

          {

            
          var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";

            
          var str = "";

            
          for(var i = 0; i < binarray.length * 4; i++)

            
          {

              str 
          += hex_tab.charAt((binarray[i>>2>> ((3 - i%4)*8+4)) & 0xF+

                     hex_tab.charAt((binarray[i
          >>2>> ((3 - i%4)*8  )) & 0xF);

            }


            
          return str;

          }


           

          /*

           * calculate MessageDigest accord to source message that inputted

           
          */


          function calcDigest()

          {

                 
          var digestM = hex_sha1(document.SHAForm.SourceMessage.value);

                 document.SHAForm.MessageDigest.value 
          = digestM;

          }


           

                        
          </script> 

                        

                        
          <title>SHA-1算法JavaScript實現(xiàn)</title>

           

                 
          </head>

                 

                 
          <body>

                        
          <center>

                               
          <BR/>

                               
          <BR/>

                               
          <H2>SHA-1算法JavaScript實現(xiàn)</H2>

                               
          <BR/>

                               
          <form name="SHAForm">

                                       源消息:
          <input type="text" name="SourceMessage" size=40><BR>

                                      消息摘要:
          <input type="text" name="MessageDigest" size=40>

                                      
          <P>

                                      
          <input type="button"  value="計算消息摘要" onclick="calcDigest()">

                               
          </form>

                 
          </body>

          </html>


          Author: orangelizq
          email: orangelizq@163.com

          歡迎大家訪問我的個人網(wǎng)站 萌萌的IT人
          posted on 2007-09-30 10:46 桔子汁 閱讀(5717) 評論(1)  編輯  收藏 所屬分類: Java技術(shù)

          評論:
          # re: SHA-1算法簡介及JavaScript實現(xiàn) 2009-07-02 16:42 | 地方
          非常清晰明了,usefull&thanks  回復(fù)  更多評論
            
          主站蜘蛛池模板: 绥棱县| 永州市| 调兵山市| 诏安县| 汶上县| 花垣县| 卢湾区| 巴彦淖尔市| 克东县| 壤塘县| 孟津县| 滦南县| 津市市| 克什克腾旗| 汤阴县| 安国市| 辽源市| 渝北区| 彰化市| 北辰区| 济宁市| 永福县| 聊城市| 盐津县| 会东县| 乐至县| 息烽县| 自贡市| 铁力市| 安陆市| 文成县| 鹤岗市| 永昌县| 井研县| 安仁县| 城固县| 常熟市| 来宾市| 黔东| 黑河市| 大竹县|