|
Duplicate :
|
|
|
Duplicate :
|
|
|
Relates :
|
|
|
Relates :
|
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Same error for:
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
When reading data from a CipherInputStream a BadPaddingException is thrown when the stream is closed before everything is read.
REGRESSION. Last worked in version 8u20
ADDITIONAL REGRESSION INFORMATION:
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
Also worked with:
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Decrypt an InputStream via CipherInputStream
- Do not read all bytes from the stream
- Close the CipherInputStream
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Close without exception
ACTUAL -
javax.crypto.BadPaddingException thrown on close
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.io.IOException: javax.crypto.BadPaddingException: Given final block not properly padded
at javax.crypto.CipherInputStream.close(CipherInputStream.java:321)
at temp.EncryptionTest.readData(EncryptionTest.java:88)
at temp.EncryptionTest.main(EncryptionTest.java:23)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.BlowfishCipher.engineDoFinal(BlowfishCipher.java:319)
at javax.crypto.Cipher.doFinal(Cipher.java:2004)
at javax.crypto.CipherInputStream.close(CipherInputStream.java:314)
... 2 more
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package temp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionTest
{
public static void main(String[] args) throws Throwable
{
EncryptionTest t = new EncryptionTest();
byte[] d = t.wirteData();
t.readData(d);
}
final static int COUNT_BYTE_TO_WRITE = 999;
final static int COUNT_BYTE_TO_READ = 99;
final static boolean ENABLE_WORKAROUND = false;
Cipher cipherOut, cipherIn;
SecretKeySpec key;
byte[] iv = new byte[8]; // Blowfish has 8 IV bytes
public EncryptionTest() throws GeneralSecurityException
{
KeyGenerator keygenerator = KeyGenerator.getInstance("Blowfish");
keygenerator.init(128);
key = new SecretKeySpec(keygenerator.generateKey().getEncoded(),
"Blowfish");
new SecureRandom().nextBytes(iv);
cipherOut = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
cipherIn = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
cipherOut.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
cipherIn.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
}
public byte[] wirteData() throws Throwable
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream oute = new CipherOutputStream(baos, cipherOut))
{
for (int i = 0; i < COUNT_BYTE_TO_WRITE; i++)
oute.write(0);
System.out.println("Write OK");
}
return baos.toByteArray();
}
public void readData(byte[] buf) throws Throwable
{
try (InputStream in = new ByteArrayInputStream(buf);
InputStream ine = new CipherInputStream(in, cipherIn))
{
for (int i = 0; i < COUNT_BYTE_TO_READ; i++)
{
int x = ine.read();
if (x != 0)
throw new RuntimeException("0 !=" + x);
}
if (ENABLE_WORKAROUND)
{// WORKAROUND: ignore all other bytes
while (ine.read() >= 0)
{
while (ine.available() > 0)
ine.skip(ine.available());
}
}
}
System.out.println("Read OK");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Add the following code before closing:
while (ine.read() >= 0)
{
while (ine.available() > 0)
ine.skip(ine.available());
}
|