Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Último bloque incompleto con CipherInputStream / CipherOutputStream, incluso con relleno AES / CBC / PKCS5Padding

En realidad, he buscado mucho de Internet y en stackoverflow también para esto,

Inicialmente no he utilizado el relleno en mi encriptación y descifrado,

Pero finalmente conseguí la solución de aquí

Https://stackoverflow.com/a/10775577/1115788

Y he actualizado mi código con relleno como AES / CBC / PKCS5Padding y el mismo error está llegando, y el último bloque no se descifra …

Estoy trabajando en esto para los últimos dos días, pero no se encontró ninguna solución

My Crypter Código:

package mani.droid.browsedropbox; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class Crypter { Cipher encipher; Cipher decipher; CipherInputStream cis; CipherOutputStream cos; FileInputStream fis; byte[] ivbytes = new byte[]{(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p'}; IvParameterSpec iv = new IvParameterSpec(ivbytes); public boolean enCrypt(String key, InputStream is, OutputStream os) { try { byte[] encoded = new BigInteger(key, 16).toByteArray(); SecretKey seckey = new SecretKeySpec(encoded, "AES"); encipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); encipher.init(Cipher.ENCRYPT_MODE, seckey, iv); cis = new CipherInputStream(is, encipher); copyByte(cis, os); return true; } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public boolean deCrypt(String key, InputStream is, OutputStream os) { try { byte[] encoded = new BigInteger(key, 16).toByteArray(); SecretKey seckey = new SecretKeySpec(encoded, "AES"); encipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); encipher.init(Cipher.DECRYPT_MODE, seckey, iv); cos = new CipherOutputStream(os, encipher); copyByte(is, cos); //cos.close(); return true; } catch (InvalidKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } public void copyByte(InputStream is, OutputStream os) throws IOException { byte[] buf = new byte[8192]; int numbytes; while((numbytes = is.read(buf)) != -1) { os.write(buf, 0, numbytes); os.flush(); } os.close(); is.close(); } } 

  • Android add padding entre los botones de los grupos de radio por programa
  • Android - Cómo configurar el relleno para TextView en ListView o ExpandableListView
  • El relleno no funciona en algunos dispositivos
  • Establecer el relleno de texto real en TextView con elementos compuestos
  • Android: establece sólo un relleno de textview mediante programación
  • Android cambia el relleno del mapa de Google en tiempo de ejecución
  • GridView y el exceso de espacio de relleno
  • El relleno no funciona en ImageButton
  • 5 Solutions collect form web for “Último bloque incompleto con CipherInputStream / CipherOutputStream, incluso con relleno AES / CBC / PKCS5Padding”

    He tenido exactamente el mismo problema. La solución aceptada funciona porque ha utilizado el modo de cifrado que no requiere relleno, pero esto no es una forma en que se solucionan los problemas relacionados con el cifrado.

    De acuerdo con la documentación CipherOutputStream, tiene que llamar al método close () para finalizar el cifrado correctamente (es decir, se agrega el bloque de relleno).

    Este método invoca el método doFinal del objeto de cifrado encapsulado, que hace que los bytes almacenados en la memoria intermedia por el cifrado encapsulado sean procesados. El resultado se escribe escribiendo el método de descarga de este flujo de salida.

    Este método restablece el objeto cifrado encapsulado en su estado inicial y llama al método close del flujo de salida subyacente.

    Si desea conservar OutputStream abierto incluso después de llamar al método CipherOutputStream.close (), puede insertar OutputStream en el flujo que no lo cierra. Por ejemplo:

     public class NotClosingOutputStream extends OutputStream { private final OutputStream os; public NotClosingOutputStream(OutputStream os) { this.os = os; } @Override public void write(int b) throws IOException { os.write(b); } @Override public void close() throws IOException { // not closing the stream. } @Override public void flush() throws IOException { os.flush(); } @Override public void write(byte[] buffer, int offset, int count) throws IOException { os.write(buffer, offset, count); } @Override public void write(byte[] buffer) throws IOException { os.write(buffer); } } 

    Entonces usted puede utilizar:

     ... cos = new CipherOutputStream(new NotClosingOutputStream(os), encipher); copyByte(is, cos); cos.close(); ... 

    Tenga en cuenta el flujo de OS no se cierra, debe hacerlo por su cuenta cuando sea apropiado.

    Finalmente tuve respuesta para mi propia pregunta, con prueba y error En realidad aquí Conflicto es que establezco Padding en encipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

    Y Set IV con algunos valores …..,

    Finalmente conseguí que la respuesta apenas substituyera el algoritmo

    De:

    AES / CBC / PKCS7Paddinng

    A:

    AES / CFB8 / NoPadding

    Y su trabajado como encanto …., Así que sugiero esta respuesta para otros que luchan con este problema, si usted resolvió problema, mencionar aquí para otros …

    He visto CipherInputStream fallar con problemas de relleno también. Este comportamiento varió entre las diferentes versiones de la JVM. Por ejemplo, 7u55 32 bit mi código funcionó bien, 7u55 64 bits mismo código falló … y también vi fallos en más tarde JVMs de 32 bits. Solución alternativa era utilizar métodos de matriz de bytes y evitar CipherInputStream.

    No estoy seguro de si esto es relevante para el problema del OP, pero esto puede ayudar a alguien.

    Cuando obtiene repetidamente que java.io.IOException: last block incomplete in decryption independientemente de lo que cambie, compruebe si todavía está utilizando el archivo de alguna ejecución anterior. Si su código de prueba de lectura / escritura se agrega a ese archivo, siempre obtendrá esa excepción, a menos que elimine el archivo dañado al que escriba.

    Utilizando CipherInputStream con relleno es posible, cambiar a NoPadding es una solución pero no una solución.

    El relleno se aplica cuando CipherInputStream llega al final de la secuencia. El punto importante es que tienes que llamar al método read () del CipherInputStream al menos dos veces para obtener todos los datos.

    En el ejemplo siguiente se muestra la lectura de un CipherInputStream con relleno:

     public static void test() throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecureRandom rnd = new SecureRandom(); byte[] keyData = new byte[16]; byte[] iv = new byte[16]; rnd.nextBytes(keyData); rnd.nextBytes(iv); SecretKeySpec key = new SecretKeySpec(keyData, "AES"); cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); CipherOutputStream out = new CipherOutputStream(buffer, cipher); byte[] plain = "Test1234567890_ABCDEFG".getBytes(); out.write(plain); out.flush(); out.close(); byte[] encrypted = buffer.toByteArray(); System.out.println("Plaintext length: " + plain.length); System.out.println("Padding length : " + (cipher.getBlockSize() - (plain.length % cipher.getBlockSize()))); System.out.println("Cipher length : " + encrypted.length); cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); CipherInputStream in = new CipherInputStream(new ByteArrayInputStream(encrypted), cipher); buffer = new ByteArrayOutputStream(); byte[] b = new byte[100]; int read; while ((read = in.read(b)) >= 0) { buffer.write(b, 0, read); } in.close(); // prints Test1234567890_ABCDEFG System.out.println(new String(buffer.toByteArray())); } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.