java AES 加密,報javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decryp
java 使用AES解密報這個異常,字面理解很容易,就是解密的字串的陣列必須是16的倍數
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:922)at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:833)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.symmetric.aes.TestAES.testDecrpyt(TestAES.java:200)
at com.symmetric.aes.TestAES.main(TestAES.java:48)
1.使用的程式碼:
package com.symmetric.aes; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; public class TestAES2 { private static final String enType_AES = "AES"; private static final String pathStr = "D://aes.key"; private static final String testStr = "AES tips you shoutld try again"; public static void main(String[] args) { SecretKey genSecretKey = testGenerateKey(); String string = genSecretKey.toString(); // byte[] testEncryptBytes = testEncryptBytes(testStr, genSecretKey); // String testDecode = testDecrptBytes(testEncryptBytes, genSecretKey); // System.out.println(testDecode); //直接運算元組,加密解密正常 String testEncrypt = testEncrypt(testStr, genSecretKey); String testDecode2 = testDecrpt(testEncrypt, genSecretKey); System.out.println(testDecode2); } /** * 生成金鑰 * 通過傳遞SecureRandom物件進行初始化 * 不指定種子或金鑰 * @return */ public static SecretKey testGenerateKey(){ SecretKey genSecretKey = null; try { KeyGenerator kGenerator = KeyGenerator.getInstance(enType_AES); SecureRandom sRandom = new SecureRandom(); kGenerator.init(sRandom);//不使用種子,每次生成的都不同 genSecretKey = kGenerator.generateKey(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return genSecretKey; } /** * 加密 * @param str * @param genSecretKey * @return */ public static byte[] testEncryptBytes(String str,SecretKey genSecretKey){ byte encrypt [] = null; try { Cipher cipher = Cipher.getInstance(enType_AES); cipher.init(Cipher.ENCRYPT_MODE, genSecretKey);//加密模式,金鑰 //cipher.update(str.getBytes()); encrypt = cipher.doFinal(str.getBytes()); } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } return encrypt; } public static String testEncrypt(String str,SecretKey genSecretKey){ byte[] testEncryptBytes = testEncryptBytes(str, genSecretKey); System.out.println(Arrays.toString(testEncryptBytes)); System.out.println("加密後的陣列長度"+testEncryptBytes.length); return (new String(testEncryptBytes)); } /** * 解密 * @param str * @param genSecretKey * @return */ public static String testDecrptBytes(byte[] bytes,SecretKey genSecretKey){ String decoderStr = null; try { Cipher cipher = Cipher.getInstance(enType_AES); cipher.init(Cipher.DECRYPT_MODE, genSecretKey);//解密模式 //cipher.update(str.getBytes()); byte[] doFinal = cipher.doFinal(bytes); decoderStr = new String(doFinal); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } return decoderStr; } public static String testDecrpt(String str,SecretKey genSecretKey){ System.out.println(Arrays.toString(str.getBytes())); System.out.println("陣列的大小"+str.getBytes().length); return testDecrptBytes(str.getBytes(), genSecretKey); } }
2.分析出現此異常的情況:
如果不把加密後的陣列拼接為字串,直接返回,然後使用這個加密後的陣列進行解密沒有任何錯誤
但是把加密後的陣列拼接為字串,然後解密時在把此字串轉為陣列,就會出現此異常
3.具體分析:
發現當把位元組陣列轉為字串後,在把字串.getBytes()獲得陣列,發現兩個位元組陣列前後不一樣了,,這是報錯的位置所在
宣告:new String(byte[]),和"str".getBytes(),兩個方法使用的編碼一樣,然後換成其他編碼也出現這樣情況
3.原因:
3.1. 為什麼陣列轉字串,字串然後轉陣列會出現,前後兩個位元組陣列的值會不同,因為並不是每個位元組數和編碼集上的字元都有對應關係,如果一個位元組數在編碼集上沒有對應,編碼new String(byte[]) 後,往往解出來的會是一些亂碼無意義的符號:例如:��,
但是解碼的時候,�這個字元也是一個字元在編碼表中也有固定的位元組數用來表示,所有解碼出來的值必定是編碼表中對應的值,除非你的位元組陣列中的位元組數正好在編碼表中有對應的值,否則編碼,解碼後的位元組陣列會不一樣
誤區: 誤以為所有的位元組陣列都可以new String(),然後在通過String.getBytes()還原
3.2.再說這個異常報:解密的位元組陣列必須是16的倍數,這得從AES的原理說起,AES是把資料按16位元組分組加密的,所有如果陣列長度不是16的倍數會報錯
AES原理:AES是對資料按128位,也就是16個位元組進行分組進行加密的,每次對一組資料加密需要執行多輪。而輸入金鑰的長度可以為128、192和256位,也就是16個位元組、24個位元組和32個位元組,如果使用者輸入的金鑰長度不是這幾種長度,也會補成這幾種長度。無論輸入金鑰是多少位元組,加密還是以16位元組的資料一組來進行的,金鑰長度的不同僅僅影響加密執行的輪數。
4.解決的辦法:
4.1 可以用base64對參生的陣列進行編碼,然後在解碼,這樣不會像new String(byte[]),getBytes()那樣造成陣列前後不一致,一開始,我看到大部分人都是用base64,我也只是以為多一層編碼看起來安全一些而已,沒想到base64對陣列的處理是不會造成誤差的
4.2 就是直接返回陣列,然後再用陣列解密咯
相關推薦
java AES 加密,報javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decryp
java 使用AES解密報這個異常,字面理解很容易,就是解密的字串的陣列必須是16的倍數javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting wi
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padd
jpa (2.1.0) +spring (3.2.7.RELEASE)+eclipseLink (2.6.3)+junit(4.12) 異常棧 2016-10-10 10:21:11 [ main:1933 ] - [ ERROR ] Caught ex
擾人的異常2: Input length must be multiple of 8 when decrypting with padded cipher
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipherat com.sun.crypto.provider.C
Android AES加密報錯處理:javax.crypto.IllegalBlockSizeException: error:1e00007b:Cipher functions:OPENSSL_internal:WRONG_FINAL_BLOCK_LENGTH
xxxxx 說明 openssl length 技術分享 可能 而不是 com bsp 一、問題說明 今天寫AES加/解密功能的apk,設想是四個控件(測試用的,界面醜這種東西請忽略) 一個編緝框----用於輸入要加密的字符串 一個文本框----用於輸出加密後的字符串,和加
Java AES 加密工具類
dom .com 生成器 ogg bytes commons level result exc package com.microwisdom.utils; import java.security.NoSuchAlgorithmException; import ja
C# 實現 JAVA AES加密解密[原創]
com base gets tran con spec ole tor 技術分享 以下是網上普遍能收到的JAVA AES加密解密方法。 因為裏面用到了KeyGenerator 和 SecureRandom,但是.NET 裏面沒有這2個類。無法使用安全隨機數生成KEY。 我們
java AES 加密解密工具(Advanced Encryption Standard)
@param key block 生成 utf i++ spec res null 1、通用方法 package com.qlkj.hzd.commom.utils; import javax.crypto.*; import java.io.Unsupported
javax crypto IllegalBlockSizeException last block incomplet
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
(Android、Java) AES加密方法
Android、Java都會使用到AES加密,方法很簡單! 先匯入包 import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.Cipher; impo
C#與Java AES 加密解密
參考文件:https://www.cnblogs.com/xbzhu/p/7064642.html 前幾天對接Java介面,需要C#加密引數,Java解密。奈何網上找了一堆大同小異的加解密方法都跟Jaca加密的密文不一致,Java介面也無法解密,直到看見上面連結的第二種方法。能夠正常的解密Java加密的
java aes加密
package com.dl.utils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec
Java AES加密 Illegal key size異常
Java實現AES加密,丟擲異常如下: java.security.InvalidKeyException: Illegal key size 原因: Illegal key size or default parameters 是指金鑰長度受限制, java執行時環境
java rsa 解密報:javax.crypto.BadPaddingException: Decryption error
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:3
JAVA AES加密 對應的 C# 方法
由於最近在專案中用到,之前在網上找了好多,來來回回,終於整出來了。 貼出來以後用起來方便 C# #region AES加解密 /// <summary> ///AES加密(加密步驟) ///1,加密字串得到2進位制陣
python合併矩陣報錯all the input arrays must have same....和vstack() takes 1 positional arrays....
python中使用numpy合併矩陣a,b 報錯 密集(dense)矩陣的合併不報錯,然而稀疏矩陣(sparse)報錯了,即在矩陣中,多數的元素為0。 ValueError: all the input arrays must have same number of
javax.mail 報錯 501 mail from address must be same as authorization user 解決方法
從一個郵箱傳送郵件 從一個郵箱傳送郵件報錯 501 mail from address must be same as authorization user,是由於獲取Session時的賬號和Message中設定的郵箱地址setFrom不一致引起的 程式碼如
elasticsearch報InvalidIndexNameException[Invalid index name [demo_indexX1], must be lowercase錯誤
cut access nta and r.java ast 相同 zed strong [demo_indexX1] InvalidIndexNameException[Invalid index name [demo_indexX1], must be lowercase
python報錯:TypeError: slice indices must be integers or None or have an __index__ method
宣告:本文為博主原創文章,不可轉載 https://blog.csdn.net/jjddss/article/details/73469104 在使用Python進行矩陣操作時,當內部含有除法時,會產生錯誤: TypeError: slice indices must be integers
python 之報錯:TypeError: write() argument must be str, not bytes
在用 pickle.dump() 儲存二進位制檔案時,一直報錯,程式如下: with open(os.path.join(FLAGS.train_data_dir, 'files.log'), 'w') as f: pickle.dump([training_paths, testing_
faster rcnn報錯:TypeError: slice indices must be integers or None or have an __index__ method
https://blog.csdn.net/qq_27637315/article/details/78849756 faster rcnn報錯:TypeError: slice indices must be integers or None or have an __index__ method