JAVA實現AES 解密報錯Input length must be multiple of 16 when decrypting with padded cipher


加密代碼

 

        /**解密
         * @param content  待解密內容
         * @param password 解密密鑰
         * @return
         */
        public static byte[] decrypt(byte[] content, String password) {
                try {
                         KeyGenerator kgen = KeyGenerator.getInstance("AES");
                         kgen.init(128, new SecureRandom(password.getBytes()));
                         SecretKey secretKey = kgen.generateKey();
                         byte[] enCodeFormat = secretKey.getEncoded();
                         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");            
                         Cipher cipher = Cipher.getInstance("AES");// 創建密碼器
                        cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
                        byte[] result = cipher.doFinal(content);
                        return result; // 加密
                } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                        e.printStackTrace();
                } catch (InvalidKeyException e) {
                        e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                        e.printStackTrace();
                } catch (BadPaddingException e) {
                        e.printStackTrace();
                }
                return null;
        }

  

 

解密代碼

        /**解密
         * @param content  待解密內容
         * @param password 解密密鑰
         * @return
         */
        public static byte[] decrypt(byte[] content, String password) {
                try {
                         KeyGenerator kgen = KeyGenerator.getInstance("AES");
                         kgen.init(128, new SecureRandom(password.getBytes()));
                         SecretKey secretKey = kgen.generateKey();
                         byte[] enCodeFormat = secretKey.getEncoded();
                         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");            
                         Cipher cipher = Cipher.getInstance("AES");// 創建密碼器
                        cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
                        byte[] result = cipher.doFinal(content);
                        return result; // 加密
                } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                        e.printStackTrace();
                } catch (InvalidKeyException e) {
                        e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                        e.printStackTrace();
                } catch (BadPaddingException e) {
                        e.printStackTrace();
                }
                return null;
        }

  

解密代碼

                String content = "test";
                String password = "12345678";
                //加密
                System.out.println("加密前:" + content);
                byte[] encryptResult = encrypt(content, password);
                try {
                        String encryptResultStr = new String(encryptResult,"utf-8");
                        //解密
                        byte[] decryptResult = decrypt(encryptResultStr.getBytes("utf-8"),password);
                        System.out.println("解密后:" + new String(decryptResult));
                } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                }

  

偶爾會報錯 拋出異常,

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
 
原因  加密后的byte數組是不能強制轉換成字符串的,換言之:字符串和byte數組在這種情況下不是互逆的;要避免這種情況,我們需要做一些修訂,可以考慮將二進制數據轉換成十六進制表示
解決方案 
 

二進制轉換成16進制

        /**將16進制轉換為二進制
         * @param hexStr
         * @return
         */
        public static byte[] parseHexStr2Byte(String hexStr) {
                if (hexStr.length() < 1)
                        return null;
                byte[] result = new byte[hexStr.length()/2];
                for (int i = 0;i< hexStr.length()/2; i++) {
                        int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
                        int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
                        result[i] = (byte) (high * 16 + low);
                }
                return result;
        }

  

16進制轉換為二進制

 
        /**將16進制轉換為二進制
         * @param hexStr
         * @return
         */
        public static byte[] parseHexStr2Byte(String hexStr) {
                if (hexStr.length() < 1)
                        return null;
                byte[] result = new byte[hexStr.length()/2];
                for (int i = 0;i< hexStr.length()/2; i++) {
                        int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
                        int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
                        result[i] = (byte) (high * 16 + low);
                }
                return result;
        }

  

 測試結果,問題解決

 

                String content = "test";
                String password = "12345678";
                //加密
                System.out.println("加密前:" + content);
                byte[] encryptResult = encrypt(content, password);
                String encryptResultStr = parseByte2HexStr(encryptResult);
                System.out.println("加密后:" + encryptResultStr);
                //解密
                byte[] decryptFrom = parseHexStr2Byte(encryptResultStr);
                byte[] decryptResult = decrypt(decryptFrom,password);
                System.out.println("解密后:" + new String(decryptResult));

  

測試結果如下:
加密前:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test
 
 
 

 


免責聲明!

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



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