DES单倍长 双倍长加密,POS机行业基本会用到

package  com.joker.utils;
 
import  java.io.UnsupportedEncodingException;
 
 
public  class  DESedeTool {
 
     /***************************** 压缩替换S-Box�? **************************************************/
 
     private  static  final  int [][] s1 = {
             14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7  },
 
             0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8  },
 
             4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0  },
 
             15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13  } };
 
     private  static  final  int [][] s2 = {
             15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10  },
 
             3 13 4 7 15 2 8 14 12 0 1 10 6 9 11 5  },
 
             0 14 7 11 10 4 13 1 5 8 12 6 9 3 2 15  },
 
             13 8 10 1 3 15 4 2 11 6 7 12 0 5 14 9  } };
 
     private  static  final  int [][] s3 = {
             10 0 9 14 6 3 15 5 1 13 12 7 11 4 2 8  },
 
             13 7 0 9 3 4 6 10 2 8 5 14 12 11 15 1  },
 
             13 6 4 9 8 15 3 0 11 1 2 12 5 10 14 7  },
 
             1 10 13 0 6 9 8 7 4 15 14 3 11 5 2 12  } };
 
     private  static  final  int [][] s4 = {
             7 13 14 3 0 6 9 10 1 2 8 5 11 12 4 15  },
 
             13 8 11 5 6 15 0 3 4 7 2 12 1 10 14 9  }, // erorr
 
             10 6 9 0 12 11 7 13 15 1 3 14 5 2 8 4  },
 
             3 15 0 6 10 1 13 8 9 4 5 11 12 7 2 14  } };
 
     private  static  final  int [][] s5 = {
             2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9  },
 
             14 11 2 12 4 7 13 1 5 0 15 10 3 9 8 6  },
 
             4 2 1 11 10 13 7 8 15 9 12 5 6 3 0 14  },
 
             11 8 12 7 1 14 2 13 6 15 0 9 10 4 5 3  } };
 
     private  static  final  int [][] s6 = {
             12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11  },
 
             10 15 4 2 7 12 9 5 6 1 13 14 0 11 3 8  },
 
             9 14 15 5 2 8 12 3 7 0 4 10 1 13 11 6  },
 
             4 3 2 12 9 5 15 10 11 14 1 7 6 0 8 13  } };
 
     private  static  final  int [][] s7 = {
             4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1  },
 
             13 0 11 7 4 9 1 10 14 3 5 12 2 15 8 6  },
 
             1 4 11 13 12 3 7 14 10 15 6 8 0 5 9 2  },
 
             6 11 13 8 1 4 10 7 9 5 0 15 14 2 3 12  } };
 
     private  static  final  int [][] s8 = {
             13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7  },
 
             1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2  },
 
             7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8  },
 
             2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11  } };
 
     private  static  final  int [] ip = {  58 50 42 34 26 18 10 2 ,
 
     60 52 44 36 28 20 12 4 ,
 
     62 54 46 38 30 22 14 6 ,
 
     64 56 48 40 32 24 16 8 ,
 
     57 49 41 33 25 17 9 1 ,
 
     59 51 43 35 27 19 11 3 ,
 
     61 53 45 37 29 21 13 5 ,
 
     63 55 47 39 31 23 15 7  };
 
     private  static  final  int [] _ip = {  40 8 48 16 56 24 64 32 ,
 
     39 7 47 15 55 23 63 31 ,
 
     38 6 46 14 54 22 62 30 ,
 
     37 5 45 13 53 21 61 29 ,
 
     36 4 44 12 52 20 60 28 ,
 
     35 3 43 11 51 19 59 27 ,
 
     34 2 42 10 50 18 58 26 ,
 
     33 1 41 9 49 17 57 25  };
 
     // 每次密钥循环左移位数
 
     private  static  final  int [] LS = {  1 1 2 2 2 2 2 2 1 2 2 2 2 2 ,
             2 1  };
 
     private  static  int [][] subKey =  new  int [ 16 ][ 48 ];
 
     private  static  int  HEX =  0 ;
 
     private  static  int  ASC =  1 ;
 
     /**
     
      * 将十六进制A--F转换成对应数�?
     
      * @param ch
     
      * @return
     
      * @throws Exception
      */
 
     public  static  int  getIntByChar( char  ch)  throws  Exception {
 
         char  t = Character.toUpperCase(ch);
 
         int  i =  0 ;
 
         switch  (t) {
 
         case  '0' :
 
         case  '1' :
 
         case  '2' :
 
         case  '3' :
 
         case  '4' :
 
         case  '5' :
 
         case  '6' :
 
         case  '7' :
 
         case  '8' :
 
         case  '9' :
 
             i = Integer.parseInt(Character.toString(t));
 
             break ;
 
         case  'A' :
 
             i =  10 ;
 
             break ;
 
         case  'B' :
 
             i =  11 ;
 
             break ;
 
         case  'C' :
 
             i =  12 ;
 
             break ;
 
         case  'D' :
 
             i =  13 ;
 
             break ;
 
         case  'E' :
 
             i =  14 ;
 
             break ;
 
         case  'F' :
 
             i =  15 ;
 
             break ;
 
         default :
 
             throw  new  Exception( "getIntByChar was wrong" );
 
         }
 
         return  i;
 
     }
 
     /**
     
      * 将字符串转换成二进制数组
     
      * @param source
      *            : 16字节
     
      * @return
      */
 
     public  static  int [] string2Binary(String source) {
 
         int  len = source.length();
 
         int [] dest =  new  int [len *  4 ];
 
         char [] arr = source.toCharArray();
 
         for  ( int  i =  0 ; i < len; i++) {
 
             int  t =  0 ;
 
             try  {
 
                 t = getIntByChar(arr[i]);
 
                 // System.out.println(arr[i]);
 
             catch  (Exception e) {
 
                 e.printStackTrace();
 
             }
 
             String[] str = Integer.toBinaryString(t).split( "" );
 
             int  k = i *  4  3 ;
 
             for  ( int  j = str.length -  1 ; j >  0 ; j--) {
 
                 dest[k] = Integer.parseInt(str[j]);
 
                 k--;
 
             }
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * 返回x的y次方
     
      * @param x
     
      * @param y
     
      * @return
      */
 
     public  static  int  getXY( int  x,  int  y) {
 
         int  temp = x;
 
         if  (y ==  0 )
             x =  1 ;
 
         for  ( int  i =  2 ; i <= y; i++) {
 
             x *= temp;
 
         }
 
         return  x;
 
     }
 
     /**
     
      * s�?位长度的二进制字符串
     
      * @param s
     
      * @return
      */
 
     public  static  String binary2Hex(String s) {
 
         int  len = s.length();
 
         int  result =  0 ;
 
         int  k =  0 ;
 
         if  (len >  4 )
             return  null ;
 
         for  ( int  i = len; i >  0 ; i--) {
 
             result += Integer.parseInt(s.substring(i -  1 , i)) * getXY( 2 , k);
 
             k++;
 
         }
 
         switch  (result) {
 
         case  0 :
 
         case  1 :
 
         case  2 :
 
         case  3 :
 
         case  4 :
 
         case  5 :
 
         case  6 :
 
         case  7 :
 
         case  8 :
 
         case  9 :
 
             return  ""  + result;
 
         case  10 :
 
             return  "A" ;
 
         case  11 :
 
             return  "B" ;
 
         case  12 :
 
             return  "C" ;
 
         case  13 :
 
             return  "D" ;
 
         case  14 :
 
             return  "E" ;
 
         case  15 :
 
             return  "F" ;
 
         default :
 
             return  null ;
 
         }
 
     }
 
     /**
     
      * 将int转换成Hex
     
      * @param i
     
      * @return
     
      * @throws Exception
      */
 
     public  static  String int2Hex( int  i) {
 
         switch  (i) {
 
         case  0 :
 
         case  1 :
 
         case  2 :
 
         case  3 :
 
         case  4 :
 
         case  5 :
 
         case  6 :
 
         case  7 :
 
         case  8 :
 
         case  9 :
 
             return  ""  + i;
 
         case  10 :
 
             return  "A" ;
 
         case  11 :
 
             return  "B" ;
 
         case  12 :
 
             return  "C" ;
 
         case  13 :
 
             return  "D" ;
 
         case  14 :
 
             return  "E" ;
 
         case  15 :
 
             return  "F" ;
 
         default :
 
             return  null ;
 
         }
 
     }
 
     /**
     
      * 将二进制字符串转换成十六进制字符�?
     
      * @param s
     
      * @return
      */
 
     public  static  String binary2ASC(String s) {
 
         String str =  "" ;
 
         int  ii =  0 ;
 
         int  len = s.length();
 
         // 不够4bit左补0
 
         if  (len %  4  !=  0 ) {
 
             while  (ii <  4  - len %  4 ) {
 
                 s =  "0"  + s;
 
             }
 
         }
 
         for  ( int  i =  0 ; i < len /  4 ; i++) {
 
             str += binary2Hex(s.substring(i *  4 , i *  4  4 ));
 
         }
 
         return  str;
 
     }
 
     /**
     
      * IP初始置换
     
      * @param source
     
      * @return
      */
 
     public  static  int [] changeIP( int [] source) {
 
         int [] dest =  new  int [ 64 ];
 
         for  ( int  i =  0 ; i <  64 ; i++) {
 
             dest[i] = source[ip[i] -  1 ];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * IP-1逆置�?
     
      * @param source
     
      * @return
      */
 
     public  static  int [] changeInverseIP( int [] source) {
 
         int [] dest =  new  int [ 64 ];
 
         for  ( int  i =  0 ; i <  64 ; i++) {
 
             dest[i] = source[_ip[i] -  1 ];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * �?2bit扩展�?8bit
     
      * @param source
     
      * @return
      */
 
     public  static  int [] expend( int [] source) {
 
         int [] ret =  new  int [ 48 ];
 
         int [] temp = {  32 1 2 3 4 5 ,
 
         4 5 6 7 8 9 ,
 
         8 9 10 11 12 13 ,
 
         12 13 14 15 16 17 ,
 
         16 17 18 19 20 21 ,
 
         20 21 22 23 24 25 ,
 
         24 25 26 27 28 29 ,
 
         28 29 30 31 32 1  };
 
         for  ( int  i =  0 ; i <  48 ; i++) {
 
             ret[i] = source[temp[i] -  1 ];
 
         }
 
         return  ret;
 
     }
 
     /**
     
      * �?8bit压缩�?2bit
     
      * @param source
      *            (48bit)
     
      * @return R(32bit)
     
      *         B=E(R)⊕K,将48 位的B 分成8 个分组,B=B1B2B3B4B5B6B7B8
      */
 
     public  static  int [] press( int [] source) {
 
         int [] ret =  new  int [ 32 ];
 
         int [][] temp =  new  int [ 8 ][ 6 ];
 
         int [][][] s = { s1, s2, s3, s4, s5, s6, s7, s8 };
 
         StringBuffer str =  new  StringBuffer();
 
         for  ( int  i =  0 ; i <  8 ; i++) {
 
             for  ( int  j =  0 ; j <  6 ; j++) {
 
                 temp[i][j] = source[i *  6  + j];
 
             }
 
         }
 
         for  ( int  i =  0 ; i <  8 ; i++) {
 
             // (16)
 
             int  x = temp[i][ 0 ] *  2  + temp[i][ 5 ];
 
             // (2345)
 
             int  y = temp[i][ 1 ] *  8  + temp[i][ 2 ] *  4  + temp[i][ 3 ] *  2
                     + temp[i][ 4 ];
 
             int  val = s[i][x][y];
 
             String ch = int2Hex(val);
 
             // System.out.println("x=" + x + ",y=" + y + "-->" + ch);
 
             // String ch = Integer.toBinaryString(val);
 
             str.append(ch);
 
         }
 
         // System.out.println(str.toString());
 
         ret = string2Binary(str.toString());
 
         // printArr(ret);
 
         // 置换P
 
         ret = dataP(ret);
 
         return  ret;
 
     }
 
     /**
     
      * 置换P(32bit)
     
      * @param source
     
      * @return
      */
 
     public  static  int [] dataP( int [] source) {
 
         int [] dest =  new  int [ 32 ];
 
         int [] temp = {  16 7 20 21 ,
 
         29 12 28 17 ,
 
         1 15 23 26 ,
 
         5 18 31 10 ,
 
         2 8 24 14 ,
 
         32 27 3 9 ,
 
         19 13 30 6 ,
 
         22 11 4 25  };
 
         int  len = source.length;
 
         for  ( int  i =  0 ; i < len; i++) {
 
             dest[i] = source[temp[i] -  1 ];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * @param R
      *            (�?2bit)
     
      * @param K
      *            (48bit的轮子密�?
     
      * @return 32bit
      */
 
     public  static  int [] f( int [] R,  int [] K) {
 
         int [] dest =  new  int [ 32 ];
 
         int [] temp =  new  int [ 48 ];
 
         // 先将输入32bit扩展�?8bit
 
         int [] expendR = expend(R); // 48bit
 
         // 与轮子密钥进行异或运�?
 
         temp = diffOr(expendR, K);
 
         // 压缩�?2bit
 
         dest = press(temp);
 
         // System.out.println("need press data----->");
 
         // printArr(temp);
 
         return  dest;
 
     }
 
     /**
     
      * 两个等长的数组做异或
     
      * @param source1
     
      * @param source2
     
      * @return
      */
 
     public  static  int [] diffOr( int [] source1,  int [] source2) {
 
         int  len = source1.length;
 
         int [] dest =  new  int [len];
 
         for  ( int  i =  0 ; i < len; i++) {
 
             dest[i] = source1[i] ^ source2[i];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * DES加密--->对称密钥
     
      * D = Ln(32bit)+Rn(32bit)
     
      * 经过16轮置�?
     
      * @param D
      *            (16byte)明文
     
      * @param K
      *            (16byte)轮子密钥
     
      * @return (16byte)密文
      */
 
     public  static  String encryption(String D, String K) {
 
         String str =  "" ;
 
         int [] temp =  new  int [ 64 ];
 
         int [] data = string2Binary(D);
 
         // printArr(data);
 
         // 第一步初始置�?
 
         data = changeIP(data);
 
         // printArr(data);
 
         int [][] left =  new  int [ 17 ][ 32 ];
 
         int [][] right =  new  int [ 17 ][ 32 ];
 
         for  ( int  j =  0 ; j <  32 ; j++) {
 
             left[ 0 ][j] = data[j];
 
             right[ 0 ][j] = data[j +  32 ];
 
         }
 
         // printArr(left[0]);
 
         // printArr(right[0]);
 
         setKey(K); // sub key ok
 
         for  ( int  i =  1 ; i <  17 ; i++) {
 
             // 获取(48bit)的轮子密�?
 
             int [] key = subKey[i -  1 ];
 
             // L1 = R0
 
             left[i] = right[i -  1 ];
 
             // R1 = L0 ^ f(R0,K1)
 
             int [] fTemp = f(right[i -  1 ], key); // 32bit
 
             right[i] = diffOr(left[i -  1 ], fTemp);
 
         }
 
         // �?��组合的时候,左右调换**************************************************
 
         for  ( int  i =  0 ; i <  32 ; i++) {
 
             temp[i] = right[ 16 ][i];
 
             temp[ 32  + i] = left[ 16 ][i];
 
         }
 
         temp = changeInverseIP(temp);
 
         str = binary2ASC(intArr2Str(temp));
 
         return  str;
 
     }
 
     /**
     
      * DES解密--->对称密钥
     
      * 解密算法与加密算法基本相同,不同之处仅在于轮子密钥的使用顺序逆序,即解密的第1
     
      * 轮子密钥为加密的�?6 轮子密钥,解密的�? 轮子密钥为加密的�?5 轮子密钥,�?…,
     
      * 解密的第16 轮子密钥为加密的�? 轮子密钥�?
     
      * @param source密文
     
      * @param key密钥
     
      * @return
      */
 
     public  static  String discryption(String source, String key) {
 
         String str =  "" ;
 
         int [] data = string2Binary(source); // 64bit
 
         // 第一步初始置�?
 
         data = changeIP(data);
 
         int [] left =  new  int [ 32 ];
 
         int [] right =  new  int [ 32 ];
 
         int [] tmp =  new  int [ 32 ];
 
         for  ( int  j =  0 ; j <  32 ; j++) {
 
             left[j] = data[j];
 
             right[j] = data[j +  32 ];
 
         }
 
         setKey(key); // sub key ok
 
         for  ( int  i =  16 ; i >  0 ; i--) {
 
             // 获取(48bit)的轮子密�?
 
             /********* 不同之处 **********/
 
             int [] sKey = subKey[i -  1 ];
 
             tmp = left;
 
             // R1 = L0
 
             left = right;
 
             // L1 = R0 ^ f(L0,K1)
 
             int [] fTemp = f(right, sKey); // 32bit
 
             right = diffOr(tmp, fTemp);
 
         }
 
         // �?��组合的时候,左右调换**************************************************
 
         for  ( int  i =  0 ; i <  32 ; i++) {
 
             data[i] = right[i];
 
             data[ 32  + i] = left[i];
 
         }
 
         data = changeInverseIP(data);
 
         for  ( int  i =  0 ; i < data.length; i++) {
 
             str += data[i];
 
         }
 
         str = binary2ASC(str);
 
         return  str;
 
     }
 
     /**
     
      * 单�?长密钥DES(16byte)
     
      * @param source
     
      * @param key
     
      * @param type
      *            0:encrypt 1:discrypt
     
      * @return
      */
 
     public  static  String DES_1(String source, String key,  int  type) {
 
         if  (source.length() !=  16  || key.length() !=  16 )
             return  null ;
 
         if  (type ==  0 ) {
 
             return  encryption(source, key);
 
         }
 
         if  (type ==  1 ) {
 
             return  discryption(source, key);
 
         }
 
         return  null ;
 
     }
 
     /**
     
     
     
      * @param source
     
      * @param key
     
      * @param type
      *            0:encrypt 1:discrypt
     
      * @return
      */
 
     public  static  String DES_2(String source, String key,  int  type) {
 
         return  null ;
 
     }
 
     /**
     
      * 三重DES算法(双�?长密�?32byte))
     
      * 密钥K1和K2
     
      * 1、先用K1加密明文
     
      * 2、接�?��K2对上�?��的结果进行解�?
     
      * 3、然后用K1对上�?��的结果进行加�?
     
      * @param source
     
      * @param key
     
      * @param type
      *            0:encrypt 1:discrypt
     
      * @return
      */
     public  static  String DES_3_new(String source, String key,  int  type) {
         
         String temp =  "" ;
         
         for ( int  i = 0 ;i<source.length()/ 16 ;i++){
             String str = source.substring(i* 16 ,(i+ 1 )* 16 );
             temp+=DES_3(str,key,type);
         }
         
         return  temp;
     }
     public  static  String DES_3(String source, String key,  int  type) {
 
         if  (key.length() !=  32  || source.length() !=  16 )
             return  null ;
 
         String temp =  null ;
 
         String K1 = key.substring( 0 , key.length() /  2 );
 
         String K2 = key.substring(key.length() /  2 );
 
//      System.out.println("K1--->" + K1);
//
//      System.out.println("K2--->" + K2);
 
         if  (type ==  0 ) {
 
             temp = encryption(source, K1);
 
//          System.out.println("step1--->" + temp);
 
             temp = discryption(temp, K2);
 
//          System.out.println("step2--->" + temp);
 
             return  encryption(temp, K1);
 
         }
 
         if  (type ==  1 ) {
 
             temp = discryption(source, K1);
 
             temp = encryption(temp, K2);
 
             return  discryption(temp, K1);
 
         }
 
         return  null ;
 
     }
 
     /************************************ 48bit的轮子密钥的生成 **********************************************************/
 
     /**
     
      * �?4bit的密钥转换成56bit
     
      * @param source
     
      * @return
      */
 
     public  static  int [] keyPC_1( int [] source) {
 
         int [] dest =  new  int [ 56 ];
 
         int [] temp = {  57 49 41 33 25 17 9 ,
 
         1 58 50 42 34 26 18 ,
 
         10 2 59 51 43 35 27 ,
 
         19 11 3 60 52 44 36 ,
 
         63 55 47 39 31 23 15 ,
 
         7 62 54 46 38 30 22 ,
 
         14 6 61 53 45 37 29 ,
 
         21 13 5 28 20 12 4  };
 
         for  ( int  i =  0 ; i <  56 ; i++) {
 
             dest[i] = source[temp[i] -  1 ];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * 将密钥循环左移i�?
     
      * @param source
      *            二进制密钥数�?
     
      * @param i
      *            循环左移位数
     
      * @return
      */
 
     public  static  int [] keyLeftMove( int [] source,  int  i) {
 
         int  temp =  0 ;
 
         int  len = source.length;
 
         int  ls = LS[i];
 
         // System.out.println("len" + len + ",LS[" + i + "]=" + ls);
 
         for  ( int  k =  0 ; k < ls; k++) {
 
             temp = source[ 0 ];
 
             for  ( int  j =  0 ; j < len -  1 ; j++) {
 
                 source[j] = source[j +  1 ];
 
             }
 
             source[len -  1 ] = temp;
 
         }
 
         return  source;
 
     }
 
     /**
     
      * �?6bit的密钥转换成48bit
     
      * @param source
     
      * @return
      */
 
     public  static  int [] keyPC_2( int [] source) {
 
         int [] dest =  new  int [ 48 ];
 
         int [] temp = {  14 17 11 24 1 5 ,
 
         3 28 15 6 21 10 ,
 
         23 19 12 4 26 8 ,
 
         16 7 27 20 13 2 ,
 
         41 52 31 37 47 55 ,
 
         30 40 51 45 33 48 ,
 
         44 49 39 56 34 53 ,
 
         46 42 50 36 29 32  };
 
         for  ( int  i =  0 ; i <  48 ; i++) {
 
             dest[i] = source[temp[i] -  1 ];
 
         }
 
         return  dest;
 
     }
 
     /**
     
      * 获取轮子密钥(48bit)
     
      * @param source
     
      * @return
      */
 
     public  static  void  setKey(String source) {
 
         if  (subKey.length >  0 )
             subKey =  new  int [ 16 ][ 48 ];
 
         // 装换�?4bit
 
         int [] temp = string2Binary(source);
 
         // �?6bit均分成两部分
 
         int [] left =  new  int [ 28 ];
 
         int [] right =  new  int [ 28 ];
 
         // 经过PC-1�?4bit转换�?6bit
 
         int [] temp1 =  new  int [ 56 ];
 
         temp1 = keyPC_1(temp);
 
         // printArr(temp1);
 
         // 将经过转换的temp1均分成两部分
 
         for  ( int  i =  0 ; i <  28 ; i++) {
 
             left[i] = temp1[i];
 
             right[i] = temp1[i +  28 ];
 
         }
 
         // 经过16次循环左移,然后PC-2置换
 
         for  ( int  i =  0 ; i <  16 ; i++) {
 
             left = keyLeftMove(left, LS[i]);
 
             right = keyLeftMove(right, LS[i]);
 
             for  ( int  j =  0 ; j <  28 ; j++) {
 
                 temp1[j] = left[j];
 
                 temp1[j +  28 ] = right[j];
 
             }
 
             // printArr(temp1);
 
             subKey[i] = keyPC_2(temp1);
 
         }
 
     }
 
     public  static  void  printArr( int [] source) {
 
         int  len = source.length;
 
         for  ( int  i =  0 ; i < len; i++) {
 
             System.out.print(source[i]);
 
         }
 
         System.out.println();
 
     }
 
     /**
     
      * 将ASC字符串转�?6进制字符�?
     
      * @param asc
     
      * @return
      */
 
     public  static  String ASC_2_HEX(String asc) {
 
         StringBuffer hex =  new  StringBuffer();
 
         try  {
 
             byte [] bs = asc.toUpperCase().getBytes( "UTF-8" );
 
             for  ( byte  b : bs) {
 
                 hex.append(Integer.toHexString( new  Byte(b).intValue()));
 
             }
 
         catch  (UnsupportedEncodingException e) {
 
             e.printStackTrace();
 
         }
 
         return  hex.toString();
 
     }
 
     /**
     
      * �?6进制的字符串转换成ASC的字符串
     
      * �?6进制的字符串压缩成BCD�?30313233343536373839414243444546)-->(0123456789ABCDEF)
     
      * @param hex
     
      * @return
      */
 
     public  static  String HEX_2_ASC(String hex) {
 
         String asc =  null ;
 
         int  len = hex.length();
 
         byte [] bs =  new  byte [len /  2 ];
 
         for  ( int  i =  0 ; i < len /  2 ; i++) {
 
             bs[i] = Byte.parseByte(hex.substring(i *  2 , i *  2  2 ),  16 );
 
         }
 
         try  {
 
             asc =  new  String(bs,  "UTF-8" );
 
         catch  (UnsupportedEncodingException e) {
 
             e.printStackTrace();
 
         }
 
         return  asc;
 
     }
 
     /**
     
      * 计算MAC(hex)
     
      * ANSI-X9.9-MAC(16的整数�?不补)
     
      * PBOC-DES-MAC(16的整数�?�?000000000000000)
     
      * 使用单�?长密钥DES算法
     
      * @param key密钥
      *            (16byte)
     
      * @param vector初始向量0000000000000000
     
      * @param data数据
     
      * @return mac
      */
 
     public  static  String MAC(String key, String vector, String data,  int  type) {
 
         if  (type == ASC) {
 
             data = ASC_2_HEX(data);
 
         }
 
         int  len = data.length();
 
         int  arrLen = len /  16  1 ;
 
         String[] D =  new  String[arrLen];
 
         if  (vector ==  null )
             vector =  "0000000000000000" ;
 
         if  (len %  16  ==  0 ) {
 
             data +=  "8000000000000000" ;
 
         else  {
 
             data +=  "80" ;
 
             for  ( int  i =  0 ; i <  15  - len %  16 ; i++) {
 
                 data +=  "00" ;
 
             }
 
         }
 
         for  ( int  i =  0 ; i < arrLen; i++) {
 
             D[i] = data.substring(i *  16 , i *  16  16 );
 
             System.out.println( "D["  + i +  "]="  + D[i]);
 
         }
 
         // D0 Xor Vector
 
         String I = xOr(D[ 0 ], vector);
 
         String O =  null ;
 
         for  ( int  i =  1 ; i < arrLen; i++) {
 
             // System.out.println(i + "**************");
 
             // System.out.println("I=" + I);
 
             O = DES_1(I, key,  0 );
 
             // System.out.println("O=" + O);
 
             I = xOr(D[i], O);
 
             // System.out.println("I=" + I);
 
         }
 
         I = DES_1(I, key,  0 );
 
         return  I;
 
     }
 
     /**
     
      * 将s1和s2做异或,然后返回
     
      * @param s1
     
      * @param s2
     
      * @return
      */
 
     public  static  String xOr(String s1, String s2) {
 
         int [] iArr = diffOr(string2Binary(s1), string2Binary(s2));
 
         return  binary2ASC(intArr2Str(iArr));
 
     }
 
     /**
     
      * 将int类型数组拼接成字符串
     
      * @param arr
     
      * @return
      */
 
     public  static  String intArr2Str( int [] arr) {
 
         StringBuffer sb =  new  StringBuffer();
 
         for  ( int  i =  0 ; i < arr.length; i++) {
 
             sb.append(arr[i]);
 
         }
 
         return  sb.toString();
 
     }
 
     /**
     
      * 将data分散
     
      * @param data
     
      * @param key
     
      * @param type
     
      * @return
      */
 
     public  static  String divData(String data, String key,  int  type) {
 
         String left =  null ;
 
         String right =  null ;
 
         if  (type == HEX) {
 
             left = key.substring( 0 16 );
 
             right = key.substring( 16 32 );
 
         }
 
         if  (type == ASC) {
 
             left = ASC_2_HEX(key.substring( 0 8 ));
 
             right = ASC_2_HEX(key.substring( 8 16 ));
 
         }
 
         // 加密
 
         data = DES_1(data, left,  0 );
 
         // 解密
 
         data = DES_1(data, right,  1 );
 
         // 加密
 
         data = DES_1(data, left,  0 );
 
         return  data;
 
     }
 
     /**
     
      * 取反(10001)--->(01110)
     
      * @param source
     
      * @return
      */
 
     public  static  String reverse(String source) {
 
         int [] data = string2Binary(source);
 
         int  j =  0 ;
 
         for  ( int  i : data) {
 
             data[j++] =  1  - i;
 
         }
 
         return  binary2ASC(intArr2Str(data));
 
     }
 
     /**
     
      * 主密钥需要经过两次分散获得IC卡中的子密钥
     
      * @param issuerFlag发卡方标识符
     
      * @param appNo应用序列号即卡号
     
      * @param mpk主密钥
     
      * @return
      */
 
     public  static  String getDPK(String issuerFlag, String appNo, String mpk) {
 
         // 第一次分散
 
         StringBuffer issuerMPK =  new  StringBuffer();
 
         // 获取Issuer MPK左半边
 
         issuerMPK.append(divData(issuerFlag, mpk,  0 ));
 
         // 获取Issuer MPK右半边
 
         issuerMPK.append(divData(reverse(issuerFlag), mpk,  0 ));
 
         // 第二次分散
 
         StringBuffer dpk =  new  StringBuffer();
 
         // 获取DPK左半边
 
         dpk.append(divData(appNo, issuerMPK.toString(),  0 ));
 
         // 获取DPK右半边
 
         dpk.append(divData(reverse(appNo), issuerMPK.toString(),  0 ));
 
         return  dpk.toString();
 
     }
     /**
     
      * 三重DES算法(双�?长密�?32byte))
     
      * 密钥K1和K2
     
      * 1、先用K1加密明文
     
      * 2、接�?��K2对上�?��的结果进行解�?
     
      * 3、然后用K1对上�?��的结果进行加�?
     
      * @param source
     
      * @param key
     
      * @param type
      *            0:encrypt 1:discrypt
     
      * @return
      */
 
     public  static  String DEDES_3(String source, String key,  int  type) {
         if  (key.length() !=  32  || source.length() !=  16 )
             return  null ;
         String temp =  null ;
         String K1 = key.substring( 0 , key.length() /  2 );
         String K2 = key.substring(key.length() /  2 );
//      System.out.println("K1--->" + K1);
//      System.out.println("K2--->" + K2);
         if  (type ==  0 ) {
             temp = encryption(source, K1);
//          System.out.println("step1--->" + temp);
             temp = discryption(temp, K2);
//          System.out.println("step2--->" + temp);
             return  encryption(temp, K1);
         }
         if  (type ==  1 ) {
             temp = discryption(source, K1);
             temp = encryption(temp, K2);
             return  discryption(temp, K1);
         }
 
         return  null ;
 
     }
     public  static  void  main(String[] args)  throws  Exception {
         //B2E8F2E11778F601
         //7576242348C58915
             System.out.println(DES_1( "3630ADF459CB24DA" "87077F2FD88BD8B8" 0 ));
             System.out.println(DES_1( "3630ADF459CB24DA" "87077F2FD88BD8B87576242348C58915" 1 ));
             
             
     }
 
}

猜你喜欢

转载自blog.csdn.net/joker_zhou/article/details/80896046