801 WORKPLACE

          追尋夢想,自由生活

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            10 Posts :: 1 Stories :: 1 Comments :: 0 Trackbacks
          最初是下載了一個寫好了的Java版SHA1,代碼如下:

          來源:http://blog.csdn.net/zyg158/archive/2007/06/26/1667531.aspx

            1public class SHA1 {
            2    private final int[] abcde = {
            3            0x674523010xefcdab890x98badcfe0x103254760xc3d2e1f0
            4        }
          ;
            5    // 摘要數據存儲數組
            6    private int[] digestInt = new int[5];
            7    // 計算過程中的臨時數據存儲數組
            8    private int[] tmpData = new int[80];
            9    // 計算sha-1摘要
           10    private int process_input_bytes(byte[] bytedata) {
           11        // 初試化常量
           12        System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
           13        // 格式化輸入字節數組,補10及長度數據
           14        byte[] newbyte = byteArrayFormatData(bytedata);
           15        // 獲取數據摘要計算的數據單元個數
           16        int MCount = newbyte.length / 64;
           17        // 循環對每個數據單元進行摘要計算
           18        for (int pos = 0; pos < MCount; pos++{
           19            // 將每個單元的數據轉換成16個整型數據,并保存到tmpData的前16個數組元素中
           20            for (int j = 0; j < 16; j++{
           21                tmpData[j] = byteArrayToInt(newbyte, (pos * 64+ (j * 4));
           22            }

           23            // 摘要計算函數
           24            encrypt();
           25        }

           26        return 20;
           27    }

           28    // 格式化輸入字節數組格式
           29    private byte[] byteArrayFormatData(byte[] bytedata) {
           30        // 補0數量
           31        int zeros = 0;
           32        // 補位后總位數
           33        int size = 0;
           34        // 原始數據長度
           35        int n = bytedata.length;
           36        // 模64后的剩余位數
           37        int m = n % 64;
           38        // 計算添加0的個數以及添加10后的總長度
           39        if (m < 56{
           40            zeros = 55 - m;
           41            size = n - m + 64;
           42        }
           else if (m == 56{
           43            zeros = 63;
           44            size = n + 8 + 64;
           45        }
           else {
           46            zeros = 63 - m + 56;
           47            size = (n + 64- m + 64;
           48        }

           49        // 補位后生成的新數組內容
           50        byte[] newbyte = new byte[size];
           51        // 復制數組的前面部分
           52        System.arraycopy(bytedata, 0, newbyte, 0, n);
           53        // 獲得數組Append數據元素的位置
           54        int l = n;
           55        // 補1操作
           56        newbyte[l++= (byte0x80;
           57        // 補0操作
           58        for (int i = 0; i < zeros; i++{
           59            newbyte[l++= (byte0x00;
           60        }

           61        // 計算數據長度,補數據長度位共8字節,長整型
           62        long N = (long) n * 8;
           63        byte h8 = (byte) (N & 0xFF);
           64        byte h7 = (byte) ((N >> 8& 0xFF);
           65        byte h6 = (byte) ((N >> 16& 0xFF);
           66        byte h5 = (byte) ((N >> 24& 0xFF);
           67        byte h4 = (byte) ((N >> 32& 0xFF);
           68        byte h3 = (byte) ((N >> 40& 0xFF);
           69        byte h2 = (byte) ((N >> 48& 0xFF);
           70        byte h1 = (byte) (N >> 56);
           71        newbyte[l++= h1;
           72        newbyte[l++= h2;
           73        newbyte[l++= h3;
           74        newbyte[l++= h4;
           75        newbyte[l++= h5;
           76        newbyte[l++= h6;
           77        newbyte[l++= h7;
           78        newbyte[l++= h8;
           79        return newbyte;
           80    }

           81    private int f1(int x, int y, int z) {
           82        return (x & y) | (~& z);
           83    }

           84    private int f2(int x, int y, int z) {
           85        return x ^ y ^ z;
           86    }

           87    private int f3(int x, int y, int z) {
           88        return (x & y) | (x & z) | (y & z);
           89    }

           90    private int f4(int x, int y) {
           91        return (x << y) | x >>> (32 - y);
           92    }

           93    // 單元摘要計算函數
           94    private void encrypt() {
           95        for (int i = 16; i <= 79; i++{
           96            tmpData[i] = f4(tmpData[i - 3^ tmpData[i - 8^ tmpData[i - 14^
           97                    tmpData[i - 16], 1);
           98        }

           99        int[] tmpabcde = new int[5];
          100        for (int i1 = 0; i1 < tmpabcde.length; i1++{
          101            tmpabcde[i1] = digestInt[i1];
          102        }

          103        for (int j = 0; j <= 19; j++{
          104            int tmp = f4(tmpabcde[0], 5+
          105                f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
          106                tmpData[j] + 0x5a827999;
          107            tmpabcde[4= tmpabcde[3];
          108            tmpabcde[3= tmpabcde[2];
          109            tmpabcde[2= f4(tmpabcde[1], 30);
          110            tmpabcde[1= tmpabcde[0];
          111            tmpabcde[0= tmp;
          112        }

          113        for (int k = 20; k <= 39; k++{
          114            int tmp = f4(tmpabcde[0], 5+
          115                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
          116                tmpData[k] + 0x6ed9eba1;
          117            tmpabcde[4= tmpabcde[3];
          118            tmpabcde[3= tmpabcde[2];
          119            tmpabcde[2= f4(tmpabcde[1], 30);
          120            tmpabcde[1= tmpabcde[0];
          121            tmpabcde[0= tmp;
          122        }

          123        for (int l = 40; l <= 59; l++{
          124            int tmp = f4(tmpabcde[0], 5+
          125                f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
          126                tmpData[l] + 0x8f1bbcdc;
          127            tmpabcde[4= tmpabcde[3];
          128            tmpabcde[3= tmpabcde[2];
          129            tmpabcde[2= f4(tmpabcde[1], 30);
          130            tmpabcde[1= tmpabcde[0];
          131            tmpabcde[0= tmp;
          132        }

          133        for (int m = 60; m <= 79; m++{
          134            int tmp = f4(tmpabcde[0], 5+
          135                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
          136                tmpData[m] + 0xca62c1d6;
          137            tmpabcde[4= tmpabcde[3];
          138            tmpabcde[3= tmpabcde[2];
          139            tmpabcde[2= f4(tmpabcde[1], 30);
          140            tmpabcde[1= tmpabcde[0];
          141            tmpabcde[0= tmp;
          142        }

          143        for (int i2 = 0; i2 < tmpabcde.length; i2++{
          144            digestInt[i2] = digestInt[i2] + tmpabcde[i2];
          145        }

          146        for (int n = 0; n < tmpData.length; n++{
          147            tmpData[n] = 0;
          148        }

          149    }

          150    // 4字節數組轉換為整數
          151    private int byteArrayToInt(byte[] bytedata, int i) {
          152        return ((bytedata[i] & 0xff<< 24| ((bytedata[i + 1& 0xff<< 16|
          153        ((bytedata[i + 2& 0xff<< 8| (bytedata[i + 3& 0xff);
          154    }

          155    // 整數轉換為4字節數組
          156    private void intToByteArray(int intValue, byte[] byteData, int i) {
          157        byteData[i] = (byte) (intValue >>> 24);
          158        byteData[i + 1= (byte) (intValue >>> 16);
          159        byteData[i + 2= (byte) (intValue >>> 8);
          160        byteData[i + 3= (byte) intValue;
          161    }

          162    // 將字節轉換為十六進制字符串
          163    private static String byteToHexString(byte ib) {
          164        char[] Digit = {
          165                '0''1''2''3''4''5''6''7''8''9''A''B''C',
          166                'D''E''F'
          167            }
          ;
          168        char[] ob = new char[2];
          169        ob[0= Digit[(ib >>> 4& 0X0F];
          170        ob[1= Digit[ib & 0X0F];
          171        String s = new String(ob);
          172        return s;
          173    }

          174    // 將字節數組轉換為十六進制字符串
          175    private static String byteArrayToHexString(byte[] bytearray) {
          176        String strDigest = "";
          177        for (int i = 0; i < bytearray.length; i++{
          178            strDigest += byteToHexString(bytearray[i]);
          179        }

          180        return strDigest;
          181    }

          182    // 計算sha-1摘要,返回相應的字節數組
          183    public byte[] getDigestOfBytes(byte[] byteData) {
          184        process_input_bytes(byteData);
          185        byte[] digest = new byte[20];
          186        for (int i = 0; i < digestInt.length; i++{
          187            intToByteArray(digestInt[i], digest, i * 4);
          188        }

          189        return digest;
          190    }

          191    // 計算sha-1摘要,返回相應的十六進制字符串
          192    public String getDigestOfString(byte[] byteData) {
          193        return byteArrayToHexString(getDigestOfBytes(byteData));
          194    }

          195    public static void main(String[] args) {
          196        String data = "1";
          197        System.out.println(data);
          198        String digest = new SHA1().getDigestOfString(data.getBytes());
          199        System.out.println(digest);
          200    }

          201}

          202

          在我們的一代令牌開發中,我們通過修改其部分源代碼(重寫sha1及相應的操作),實現otp在Android平臺上的實現。其實我的工作量并不大,只是按要求把代碼改了改,寫一個SHA1類,加入了三個函數,包含初始化,數據更新,更新輸出。以修改源代碼中的過耦合現象,即digestInt數據不被隨便修改,將其初始化過程實現在初始化函數中。

          代碼如下:
          /**
          * SHA1類,主要包含encrypt,init,upData,doFinal函數
          @author Snowolf
          *
          */public class SHA1{    
              
          private final int[] abcde = {
                      
          0x674523010xefcdab890x98badcfe0x103254760xc3d2e1f0
                  };
          // 摘要數據存儲數組
              private int[] digestInt = new int[5];
            
          // 計算過程中的臨時數據存儲數組
                 private int[] tmpData = new int[80];
              
          /**
               * f1是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
               * 
          @param x 32位字
               * 
          @param y 32位字
               * 
          @param z 32位字
               * 
          @return 運算結果
               
          */
              
          private int f1(int x, int y, int z) {
                  
          return (x & y) | (~& z);
              }
              
          /**
               * f2是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
               * 
          @param x 32位字
               * 
          @param y 32位字
               * 
          @param z 32位字
               * 
          @return 運算結果
               
          */
              
          private int f2(int x, int y, int z) {
                  
          return x ^ y ^ z;
              }
              
          /**
               * f3是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
               * 
          @param x 32位字
               * 
          @param y 32位字
               * 
          @param z 32位字
               * 
          @return 運算結果
               
          */
              
          private int f3(int x, int y, int z) {
                  
          return (x & y) | (x & z) | (y & z);
              }
              
          /**
               * f4是循環移位函數,將x進行循環移位,移位次數為y
               * 
          @param x 要移位的字
               * 
          @param y 移位次數
               * 
          @return 運算結果
               
          */
              
          private int f4(int x, int y) {
                  
          return (x << y) | x >>> (32 - y);
              }
              
          /**
               * 單元摘要計算函數,函數運算完成后,最終結果儲存在digestInt中
               * 
          @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
               * 
          @return void
               * 
          @author Snowolf
               
          */
              
          private void encrypt(int[] Message_Block) {
                  
          for(int t = 0; t < 16; t++)
                  {
                      tmpData[t] 
          = Message_Block[t];
                  }
                  
          for (int i = 16; i <= 79; i++) {
                      tmpData[i] 
          = f4(tmpData[i - 3^ tmpData[i - 8^ tmpData[i - 14^
                              tmpData[i 
          - 16], 1);
                  }
                  
          int[] tmpabcde = new int[5];
                  
          for (int i1 = 0; i1 < tmpabcde.length; i1++) {
                      tmpabcde[i1] 
          = digestInt[i1]; 
                  }
                  
          for (int j = 0; j <= 19; j++) {
                      
          int tmp = f4(tmpabcde[0], 5+
                          f1(tmpabcde[
          1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
                          tmpData[j] 
          + 0x5a827999;
                      tmpabcde[
          4= tmpabcde[3];
                      tmpabcde[
          3= tmpabcde[2];
                      tmpabcde[
          2= f4(tmpabcde[1], 30);
                      tmpabcde[
          1= tmpabcde[0];
                      tmpabcde[
          0= tmp;
                  }
                  
          for (int k = 20; k <= 39; k++) {
                      
          int tmp = f4(tmpabcde[0], 5+
                          f2(tmpabcde[
          1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
                          tmpData[k] 
          + 0x6ed9eba1;
                      tmpabcde[
          4= tmpabcde[3];
                      tmpabcde[
          3= tmpabcde[2];
                      tmpabcde[
          2= f4(tmpabcde[1], 30);
                      tmpabcde[
          1= tmpabcde[0];
                      tmpabcde[
          0= tmp;
                  }
                  
          for (int l = 40; l <= 59; l++) {
                      
          int tmp = f4(tmpabcde[0], 5+
                          f3(tmpabcde[
          1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
                          tmpData[l] 
          + 0x8f1bbcdc;
                      tmpabcde[
          4= tmpabcde[3];
                      tmpabcde[
          3= tmpabcde[2];
                      tmpabcde[
          2= f4(tmpabcde[1], 30);
                      tmpabcde[
          1= tmpabcde[0];
                      tmpabcde[
          0= tmp;
                  }
                  
          for (int m = 60; m <= 79; m++) {
                      
          int tmp = f4(tmpabcde[0], 5+
                          f2(tmpabcde[
          1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
                          tmpData[m] 
          + 0xca62c1d6;
                      tmpabcde[
          4= tmpabcde[3];
                      tmpabcde[
          3= tmpabcde[2];
                      tmpabcde[
          2= f4(tmpabcde[1], 30);
                      tmpabcde[
          1= tmpabcde[0];
                      tmpabcde[
          0= tmp;
                  }
                  
          for (int i2 = 0; i2 < tmpabcde.length; i2++) {
                      digestInt[i2] 
          = digestInt[i2] + tmpabcde[i2];//摘要存儲在digestInt
                  }
                  
          for (int n = 0; n < tmpData.length; n++) {
                      tmpData[n] 
          = 0;
                  }
              }
              
          /**
               * 初始化函數,將digestInt值初始化為SHA1算法中的原始初值
               
          */
              
          public void init(){       
                  System.arraycopy(abcde, 
          0, digestInt, 0, abcde.length);
              }
              
          /** SHA1加密運算,其中updata返回值為void,此時digestInt中的數據為計算結果(摘要)
               *為16個字的int型數組,即我們已經格式化完成的數據
               * 
          @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
               * 
          @author Snowolf
               
          */
              
          public void upData(int[] Message_Block){
                  encrypt(Message_Block);
              }
              
          /**
               * SHA1加密運算,返回值為int[],即返回計算出來的摘要
               * 
          @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
               * 
          @return int[5]摘要
               * 
          @author Snowolf
               
          */
              
          public int[] doFinal(int[] Message_Block){
                  
          int[] doFinalInt = new int[5];
                  encrypt(Message_Block);
                  System.arraycopy(digestInt, 
          0, doFinalInt, 0, digestInt.length);
                  
          return doFinalInt;
              }
          }



          代碼如下:

            1/**
            2* SHA1類,主要包含encrypt,init,upData,doFinal函數
            3@author Snowolf
            4*
            5*/

            6public class SHA1{    
            7    private final int[] abcde = {
            8            0x674523010xefcdab890x98badcfe0x103254760xc3d2e1f0
            9        }
          ;
           10// 摘要數據存儲數組
           11    private int[] digestInt = new int[5];
           12  // 計算過程中的臨時數據存儲數組
           13    
           14    private int[] tmpData = new int[80];
           15    /**
           16     * f1是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
           17     * @param x 32位字
           18     * @param y 32位字
           19     * @param z 32位字
           20     * @return 運算結果
           21     */

           22    private int f1(int x, int y, int z) {
           23        return (x & y) | (~& z);
           24    }

           25    /**
           26     * f2是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
           27     * @param x 32位字
           28     * @param y 32位字
           29     * @param z 32位字
           30     * @return 運算結果
           31     */

           32    private int f2(int x, int y, int z) {
           33        return x ^ y ^ z;
           34    }

           35    /**
           36     * f3是SHA1算法中的一系列函數中的一個,操作32位字x,y,z并且產生32位字作為輸出
           37     * @param x 32位字
           38     * @param y 32位字
           39     * @param z 32位字
           40     * @return 運算結果
           41     */

           42    private int f3(int x, int y, int z) {
           43        return (x & y) | (x & z) | (y & z);
           44    }

           45    /**
           46     * f4是循環移位函數,將x進行循環移位,移位次數為y
           47     * @param x 要移位的字
           48     * @param y 移位次數
           49     * @return 運算結果
           50     */

           51    private int f4(int x, int y) {
           52        return (x << y) | x >>> (32 - y);
           53    }

           54    /**
           55     * 單元摘要計算函數,函數運算完成后,最終結果儲存在digestInt中
           56     * @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
           57     * @return void
           58     * @author Snowolf
           59     */

           60    private void encrypt(int[] Message_Block) {
           61        for(int t = 0; t < 16; t++)
           62        {
           63            tmpData[t] = Message_Block[t];
           64        }

           65        for (int i = 16; i <= 79; i++{
           66            tmpData[i] = f4(tmpData[i - 3^ tmpData[i - 8^ tmpData[i - 14^
           67                    tmpData[i - 16], 1);
           68        }

           69        int[] tmpabcde = new int[5];
           70        for (int i1 = 0; i1 < tmpabcde.length; i1++{
           71            tmpabcde[i1] = digestInt[i1]; 
           72        }

           73        for (int j = 0; j <= 19; j++{
           74            int tmp = f4(tmpabcde[0], 5+
           75                f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
           76                tmpData[j] + 0x5a827999;
           77            tmpabcde[4= tmpabcde[3];
           78            tmpabcde[3= tmpabcde[2];
           79            tmpabcde[2= f4(tmpabcde[1], 30);
           80            tmpabcde[1= tmpabcde[0];
           81            tmpabcde[0= tmp;
           82        }

           83        for (int k = 20; k <= 39; k++{
           84            int tmp = f4(tmpabcde[0], 5+
           85                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
           86                tmpData[k] + 0x6ed9eba1;
           87            tmpabcde[4= tmpabcde[3];
           88            tmpabcde[3= tmpabcde[2];
           89            tmpabcde[2= f4(tmpabcde[1], 30);
           90            tmpabcde[1= tmpabcde[0];
           91            tmpabcde[0= tmp;
           92        }

           93        for (int l = 40; l <= 59; l++{
           94            int tmp = f4(tmpabcde[0], 5+
           95                f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
           96                tmpData[l] + 0x8f1bbcdc;
           97            tmpabcde[4= tmpabcde[3];
           98            tmpabcde[3= tmpabcde[2];
           99            tmpabcde[2= f4(tmpabcde[1], 30);
          100            tmpabcde[1= tmpabcde[0];
          101            tmpabcde[0= tmp;
          102        }

          103        for (int m = 60; m <= 79; m++{
          104            int tmp = f4(tmpabcde[0], 5+
          105                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4+
          106                tmpData[m] + 0xca62c1d6;
          107            tmpabcde[4= tmpabcde[3];
          108            tmpabcde[3= tmpabcde[2];
          109            tmpabcde[2= f4(tmpabcde[1], 30);
          110            tmpabcde[1= tmpabcde[0];
          111            tmpabcde[0= tmp;
          112        }

          113        for (int i2 = 0; i2 < tmpabcde.length; i2++{
          114            digestInt[i2] = digestInt[i2] + tmpabcde[i2];//摘要存儲在digestInt
          115        }

          116        for (int n = 0; n < tmpData.length; n++{
          117            tmpData[n] = 0;
          118        }

          119    }

          120    /**
          121     * 初始化函數,將digestInt值初始化為SHA1算法中的原始初值
          122     */

          123    public void init(){       
          124        System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
          125    }

          126    /** SHA1加密運算,其中updata返回值為void,此時digestInt中的數據為計算結果(摘要)
          127     *為16個字的int型數組,即我們已經格式化完成的數據
          128     * @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
          129     * @author Snowolf
          130     */

          131    public void upData(int[] Message_Block){
          132        encrypt(Message_Block);
          133    }

          134    /**
          135     * SHA1加密運算,返回值為int[],即返回計算出來的摘要
          136     * @param Message_Block 為大小16個字的int型數組,即我們已經格式化完成的,要進行加密運算的數據
          137     * @return int[5]摘要
          138     * @author Snowolf
          139     */

          140    public int[] doFinal(int[] Message_Block){
          141        int[] doFinalInt = new int[5];
          142        encrypt(Message_Block);
          143        System.arraycopy(digestInt, 0, doFinalInt, 0, digestInt.length);
          144        return doFinalInt;
          145    }

          146}

          147
          posted on 2010-11-22 14:48 WangShishuai 閱讀(1130) 評論(1)  編輯  收藏 所屬分類: AndroidJava加密算法

          Feedback

          # re: SHA-1的Java實現 及在otp中的使用 2013-04-30 01:40 M.LI
          你好:我在讀你的http://www.aygfsteel.com/BigForest/archive/2010/11/22/338691.html
          這個文章,我是菜鳥想借鑒一下在OTP中的使用,但是我沒找到在里面 的用法,求指導……
          我 的郵箱hpucode@gmail.com  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 赤水市| 祁东县| 清河县| 旌德县| 耒阳市| 布尔津县| 西乡县| 含山县| 丰城市| 普兰县| 阿合奇县| 调兵山市| 阳谷县| 青河县| 娱乐| 韩城市| 米泉市| 遵义市| 苍溪县| 紫金县| 册亨县| 夏津县| 顺义区| 金坛市| 祁连县| 洪洞县| 灵台县| 邵阳县| 凉山| 长沙县| 涿鹿县| 图木舒克市| 长丰县| 梨树县| 海南省| 垣曲县| 洪雅县| 合水县| 务川| 怀安县| 西平县|