6.Java復号技術シリーズの3 DES

8750 ワード

Java復号技術シリーズの3 DES
 
  • シーケンス
  • 背景
  • コンセプト
  • 原理
  • コード実装
  • 終了語
  •  
    シーケンス
    前の文章は対称暗号化アルゴリズムであるDESについて話しています.この文章はDESに基づいて、3重DESであるTriple DESについてもっと話し続けるつもりです.
    背景
    3 DESはなぜ現れたのでしょうか.実は、これは難しくないです.DESは非常に簡便な暗号化アルゴリズムであるが,鍵長が短く計算量が小さく,比較的解読しやすい.したがって,DESに基づいて三重データ暗号化アルゴリズムを用いてデータを暗号化することで,解読の確率はかなり小さくなる.
    コンセプト
    3 DES、すなわち「Triple DES」は、中国語名の「三重データ暗号化アルゴリズム」であり、各データブロックに3回のDES暗号化アルゴリズムを適用することに相当する.コンピュータの演算能力が強化されたため、原版DESパスワードの鍵の長さは暴力的に解読されやすくなった.3 DESは、新しいブロック暗号アルゴリズムを設計するのではなく、DESの鍵長を増加させることによって類似の攻撃を回避する比較的簡単な方法を提供するように設計されている.
    げんり
    56ビットの鍵3つを使用してデータを3回暗号化します.3 DES(Triple DES)は、DESからAESへの移行の暗号化アルゴリズムである(1999年、NISTは3-DESを移行の暗号化基準として指定した).
    具体的には、Ek()およびDk()がDESアルゴリズムの暗号化および復号化プロセスを表し、KがDESアルゴリズムで使用される鍵を表し、Pが明文を表し、Cが密文を表すとする.
    3 DES暗号化プロセス:
    C = Ek3 ( Dk2 ( Ek1 ( P ) ) )
    3 DESの復号処理は次のとおりです.
    P = Dk1 ( EK2 ( Dk3 ( C ) ) )
    コード実装
    3 DESのコード実装は、DESと似ていますが、実は前の記事であるDESのコード実装を参考にして、アルゴリズム定義をDESedeに変更すればよいのです.ただし,参照の利便性を考慮して,ここでは3 DES復号化のコード実装を貼り付けて参照する.
    import javax.crypto.Cipher;  
    import javax.crypto.SecretKey;  
    import javax.crypto.spec.SecretKeySpec;  
    import java.io.ByteArrayOutputStream;  
    import java.security.Security;  
      
    /** 
     * Created by xiang.li on 2015/3/19. 
     * TripleDES(3DES)        
     */  
    public class TripleDES {  
        private static final String Algorithm = "DESede"; //        ,   DES,DESede,Blowfish  
        private static final String hexString="0123456789ABCDEF";  
        /** 
         * 
         * @param keybyte      ,   24   
         * @param src         (               。 ) 
         * @return 
         */  
        public static byte[] encryptMode(byte[] keybyte, byte[] src) {  
            try {  
                //                     
                SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);  
                //     
                Cipher c1 = Cipher.getInstance(Algorithm);  
                c1.init(Cipher.ENCRYPT_MODE, deskey);  
                return c1.doFinal(src);  
            } catch (java.security.NoSuchAlgorithmException e1) {  
                e1.printStackTrace();  
            } catch (javax.crypto.NoSuchPaddingException e2) {  
                e2.printStackTrace();  
            } catch (java.lang.Exception e3) {  
                e3.printStackTrace();  
            }  
            return null;  
        }  
      
        /** 
         * 
         * @param keybyte    
         * @param src               
         * @return 
         */  
        public static byte[] decryptMode(byte[] keybyte, byte[] src) {  
            try {  
                //       
                SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);  
                //     
                Cipher c1 = Cipher.getInstance(Algorithm);  
                c1.init(Cipher.DECRYPT_MODE, deskey);  
                return c1.doFinal(src);  
            } catch (java.security.NoSuchAlgorithmException e1) {  
                e1.printStackTrace();  
            } catch (javax.crypto.NoSuchPaddingException e2) {  
                e2.printStackTrace();  
            } catch (java.lang.Exception e3) {  
                e3.printStackTrace();  
            }  
            return null;  
        }  
      
        /** 
         *      16   
         * @param str 
         * @return 
         */  
        public static String encode(String str)  
        {  
            //              
            byte[] bytes=str.getBytes();  
            StringBuilder sb=new StringBuilder(bytes.length*2);  
      
            //             2 16      
            for(int i=0;i<bytes.length;i++)  
            {  
                sb.append(hexString.charAt((bytes[i]&0xf0)>>4));  
                sb.append(hexString.charAt((bytes[i]&0x0f)>>0));  
            }  
            return sb.toString();  
        }  
        /** 
         * 
         * @param bytes 
         * @return 
         *  16          ,       (    ) 
         */  
        public static String decode(String bytes)  
        {  
            ByteArrayOutputStream baos=new ByteArrayOutputStream(bytes.length()/2);  
            //  2 16             
            for(int i=0;i<bytes.length();i+=2)  
                baos.write((hexString.indexOf(bytes.charAt(i))<<4 |hexString.indexOf(bytes.charAt(i+1))));  
            return new String(baos.toByteArray());  
        }  
      
        //             
        public static String byte2hex(byte[] b) {  
            String hs = "";  
            String stmp = "";  
            for (int n = 0; n < b.length; n++) {  
                stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));  
                if (stmp.length() == 1)  
                    hs = hs + "0" + stmp;  
                else  
                    hs = hs + stmp;  
                if (n < b.length - 1)  
                    hs = hs + "";  
            }  
            return hs.toUpperCase();  
        }  
      
        public static void main(String[] args) {  
            //        ,   JCE          
            //  addProvider                (            ,   )  
            Security.addProvider(new com.sun.crypto.provider.SunJCE());  
            //byte  (       )  
            final byte[] keyBytes = { 0x11, 0x22, 0x4F, 0x58, (byte)0x88, 0x10,  
                    0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD,  
                    0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36,  
                    (byte) 0xE2 };  
            String szSrc = "This is a 3DES test.   ";  
            System.out.println("       :" + szSrc);  
      
            byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());  
            System.out.println("       :" + byte2hex(encoded));  
      
            byte[] srcBytes = decryptMode(keyBytes, encoded);  
            System.out.println("       :" + new String(srcBytes));  
        }  
    }