記一次文件編碼出現的BUG javax.crypto.BadPaddingException: Given final block not properly padded

1.前景:工做中須要實現一個功能,導出的數據須要加密,不能被明文看到,使用DES加密,對byte數組加密解密操做代碼以下java

public class DESTool {
  static String transformation = "DESede/ECB/PKCS5Padding";
    static String algorithm = "DESede";
  public byte[] decode(byte[] srcByte, byte[] keyByte, int offset, int length) throws Exception, NoSuchAlgorithmException {
//        DESKeySpec spec = new DESKeySpec(keyByte);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        SecretKey secretKey = new SecretKeySpec(keyByte, algorithm);
//        KeySpec spec = new SecretKeySpec(keyByte, algorithm);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] b = cipher.doFinal(srcByte, offset, length);
        return b;
    }
  public byte[] encode(byte[] srcByte, byte[] keyByte, int offset, int length) throws Exception, NoSuchAlgorithmException {
//        DESKeySpec spec = new DESKeySpec(keyByte);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        SecretKey secretKey = new SecretKeySpec(keyByte, algorithm);
//        KeySpec spec = new SecretKeySpec(keyByte, algorithm);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] b = cipher.doFinal(srcByte, offset, length);
        return b;
    }
}

2.在使用如上方法進行加解密時,因爲文件大小是不肯定的,因此使用分批次加解密,一次加解密50*1024個bytelinux

3.自主測試沒有問題,可是測試環境上出現問題,堆棧信息以下數據庫

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

4.網上搜索答案都是說一些linux上SecretKey獲取的問題,可是和本人工做中的情況不符,本人工做中windows開發環境上加密導出的文件去測試環境導入是能夠正常導入的,而且本人寫了測試類,編譯成class文件後去測試環境執行class文件,加解密沒有問題,因此這個可能性排除windows

5.因而我要來了測試環境的數據庫鏈接信息,本地鏈接測試數據庫,同時導出未加密的明文文件和加密的密文文件,以後對明文文件加密以後和密文文件逐字節進行對比,對比結果徹底同樣數組

6.最後想到加密解密是按本身進行的,會不會是加解密的字節長度致使的,因而我把測試類中加密明文文件時使用的字節數組長度設置爲5*1024,而不是50*1024,以後加密,再和密文文件逐字節對比,果真出現了不一樣,ide

7.最後經測試,需加密的字節長度和加密結果的字節長度存在如下關係:加密結果字節長度 = (需加密字節長度/8)* 8 + 8;因而我把解密時字節長度改成了50*1024+8,問題解決測試

8.結論:加密過程當中字節長度可能會變化,所以解密時字節長度應該和加密時字節長度存在必定的相關關係,不能隨便設置。加密

相關文章
相關標籤/搜索