儘管我發現很多關於同一問題的帖子,但我無法解決我的問題。javax.crypto.IllegalBlockSizeException使用AES
我正在使用c#服務器和一個java客戶端(將來會是android)。好奇的是我正在發送/接收很多更長,更復雜的json字符串,並且只是最短和最簡單的失敗。
這是客戶端的代碼:
private static byte[] asegurarCapacidad(byte[] inicial, int tamano){
if(inicial.length<tamano){
return Arrays.copyOf(inicial, tamano);
}
return inicial;
}
private static String leer(Socket s){
byte[] buffer=new byte[4092];
byte[] bufferFinal = new byte[8092];
int leido=0;
int posicion=0;
String salida = null;
try {
SecretKey key = new SecretKeySpec("1212121212121212".getBytes("UTF-8"),"AES");
DataInputStream dis=new DataInputStream(s.getInputStream());
while((leido=dis.read(buffer))>0){
bufferFinal=asegurarCapacidad(bufferFinal,posicion+leido);
System.arraycopy(buffer, 0, bufferFinal, posicion, leido);
posicion+=leido;
}
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key,iv);
salida=decodificar(cipher.doFinal(bufferFinal));
} catch (Throwable e) {
System.out.println("CLIENTE: ERROR AL LEER: "+e);
e.printStackTrace();
}
return salida;
}
這是服務器的代碼:
private static byte[] codificar(string mensaje)
{
return System.Text.Encoding.UTF8.GetBytes(mensaje);
}
private static void escribir(Socket s, string mensaje)
{
byte[] buffer = new byte[mensaje.Length];
buffer = codificar(mensaje);
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Key = bytKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.IV = iv;
ICryptoTransform AESEncrypt = aes.CreateEncryptor();
buffer = AESEncrypt.TransformFinalBlock(buffer, 0, buffer.Length);
s.Send(buffer);
}
任何建議將受到歡迎。
不是專家,但你使用PKCS7填充加密,並與PKCS5Padding解密。我的猜測是,你用Java讀取字節的方式是不正確的:你將bufferFinal分配給一個大字節數組,然後立即用asegurarCapacidad()的結果重新分配它,這沒有顯示。爲什麼不將每個讀取的字節都發送給ByteArrayOutputStream,或者直接發送給Cipher? –
@JBNizet PKCS#7和PKCS#5基本上是相同的,只是名稱不同(除了PKCS#5僅針對64位塊定義,因此在Java中有點用詞不當)。 – ntoskrnl
@ntoskrnl:謝謝你的信息。 –