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()); }
|