JAVA实现AES 解密报错Input length must be multiple of 16 when decrypting with padded cipher
生活随笔
收集整理的這篇文章主要介紹了
JAVA实现AES 解密报错Input length must be multiple of 16 when decrypting with padded cipher
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
加密代碼
/*** 加密* * @param content 需要加密的內(nèi)容* @param password 加密密碼* @return*/public static byte[] encrypt(String 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");// 創(chuàng)建密碼器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(byteContent);return result; // 加密} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}解密代碼
/**解密* 解密的時(shí)候要傳入byte數(shù)組* @param content 待解密內(nèi)容* @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");// 創(chuàng)建密碼器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;}測(cè)試代碼
String content = "test";String password = "12345678";//加密System.out.println("加密前:" + content);byte[] encryptResult = encrypt(content, password);//解密byte[] decryptResult = decrypt(encryptResult,password);System.out.println("解密后:" + new String(decryptResult));輸出結(jié)果如下:
加密前:test
解密后:test
容易出錯(cuò)的地方:
如果我們將測(cè)試代碼修改一下,如下:
則,系統(tǒng)會(huì)報(bào)出如下異常:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipherat com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)at javax.crypto.Cipher.doFinal(DashoA13*..)這主要是因?yàn)榧用芎蟮腷yte數(shù)組是不能強(qiáng)制轉(zhuǎn)換成字符串的,換言之:字符串和byte數(shù)組在這種情況下不是互逆的;要避免這種情況,我們需要做一些修訂,可以考慮將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成十六進(jìn)制表示,主要有如下兩個(gè)方法:
二進(jìn)制轉(zhuǎn)換成16進(jìn)制
/**將二進(jìn)制轉(zhuǎn)換成16進(jìn)制* @param buf* @return*/public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}16進(jìn)制轉(zhuǎn)換為二進(jìn)制
/**將16進(jìn)制轉(zhuǎn)換為二進(jìn)制* @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;}然后,我們?cè)傩抻喴陨蠝y(cè)試代碼,如下:
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));測(cè)試結(jié)果如下:
加密前:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test
另外一種加密方式
/*** 加密** @param content 需要加密的內(nèi)容* @param password 加密密碼* @return*/public static byte[] encrypt2(String content, String password) {try {SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result = cipher.doFinal(byteContent);return result; // 加密} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;} 這種加密方式有兩種限制 密鑰必須是16位的 待加密內(nèi)容的長(zhǎng)度必須是16的倍數(shù),如果不是16的倍數(shù),就會(huì)出如下異常: javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytesat com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)at javax.crypto.Cipher.doFinal(DashoA13*..)要解決如上異常,可以通過補(bǔ)全傳入加密內(nèi)容等方式進(jìn)行避免。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的JAVA实现AES 解密报错Input length must be multiple of 16 when decrypting with padded cipher的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git添加为远程仓库
- 下一篇: 工作流实战_20_flowable 任务