java 3des加密問題記錄



3des加密有不同的加密模式和填充模式,這個網上很多不多說了,只要保證加解密的時候加密模式和填充模式保持一致就可以了
首先對於密鑰的生成,java中有2種方式:
1.第一種,采用ECB模式和不填充模式
//加密 public static byte[] des3EncodeECB(byte[] key, byte[] data) throws Exception { Key deskey = null; SecretKeySpec spec = new SecretKeySpec(key,"desede"); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede" + "/ECB/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, deskey); byte[] bOut = cipher.doFinal(data); return bOut; } //解密 public static byte[] des3DecodeECB(byte[] key, byte[] data) throws Exception { Key deskey = null; SecretKeySpec spec = new SecretKeySpec(key,"desede"); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("DESede" + "/ECB/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, deskey); byte[] bOut = cipher.doFinal(data); return bOut; }

2.第二種,同樣采用ECB模式和不填充模式
//加密
    public static byte[] encrypt(byte[] targetToByte, String algorithm,String mode, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, getKey(key, mode));
        byte[] result = cipher.doFinal(targetToByte);
        // System.out.println("base64:" +encryptByBase64(result));
        return result;
    }
//解密
    public static byte[] decrypt(byte[] targetToByte, String algorithm,String mode, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, getKey(key, mode));
        byte[] result = cipher.doFinal(targetToByte);
        // System.out.println("base:" + new String(result,"UTF-8"));
        return result;
    }
 
    public static Key getKey(String key, String algorithm) {
        try {
            KeyGenerator generator = KeyGenerator.getInstance(algorithm);
            //注意此處將key按照16進制數字解析成byte數組,按需要修改,比如key.getBytes()
            generator.init(new SecureRandom(HexString2Bytes(key)));
            return generator.generateKey();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 

   兩種方式的區別,第一種就是使用你給定的key作為密鑰,當與其他客戶端進行通信,加解密不是由同一方操作的時候推薦使用,第二種是根據你給的key來生成一個新的key,這個新的key才是真正加密時使用的key,所以如果用第一種加密出來的密文用第二種來解密,是解不出來的。
  另外,java中只提供了3倍長3des的算法,也就是key的長度必須是24字節,如果想要使用2倍長3des,需要自己將后8個字節補全(就是將16個字節的前8個字節補到最后,變成24字節)。如果提供的key不足24字節,將會報錯,如果超過24字節,將會截取前24字節作為key(坑了我好長時間)
 
3des的加密過程
3DES,分為2種,一個是雙倍長3DES,一個是三倍長3DES。
如果是雙倍長3DES,密鑰為16字節長,按左右,分別LK(密鑰的左邊8字節),RK(密鑰的右邊8字節)。加密內容DATA為8字節。
假設單倍長DES加密過程為:DES( data, key, dest ),其中,data為被加密數據,key為加密密鑰,dest為加密結果。單倍長DES解密過程為:UDES(data, key, dest ),其中,data為被解密的數據,key為解密密鑰,dest為解密結果。
那么,雙倍長3DES的加密方法為:
DES( DATA, LK, TMP1 );
UDES( TMP1, RK, TMP2 );
DES( DATA, LK, DEST );
DEST是最終得到的密文。具體過程簡述如下:
1)使用密鑰的前8字節,對數據DATA進行加密,得到加密的結果TMP1;
2)使用密鑰的后8字節,對第一的計算結果TMP1,進行解密,得到解密的結果TMP2;
3)再次使用密鑰的前8字節,對第二次的計算結果TMP2,進行加密,得到加密的結果DEST。DEST就為最終的結果。
對於三倍長3DES,密鑰長度的為24字節長。可以分為LK(密鑰的左邊8字節),CK(密鑰的中間8字節),RK(密鑰的左邊8字節)。與二倍長3DES的加密過程基本相同,只是第一次計算,使用密鑰LK;第二次計算,使用密鑰CK;第三次計算,使用密鑰LK。基本過程如下:
DES( DATA, LK, TMP1 );
UDES( TMP1, CK, TMP2 );
DES( TMP2, RK, DEST );
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM