Java.lang.IllegalStateException: Cifrado no inicializado

He implementado el cifrado / descifrado en la aplicación de Android.

He añadido una clase de cifrado que se ha hecho una clase Singleton.

Parte del código como sigue:

public class Encryption { private SecretKeySpec mKey = null; private Cipher mCipher = null; private byte[] mKeyBytes = null; private AlgorithmParameterSpec mParamSpec = null; private static Encryption sInstance; public Encryption() { byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; mParamSpec = new IvParameterSpec(iv); mKeyBytes = getMD5(MD5_KEY.getBytes(); mKey = new SecretKeySpec(mKeyBytes, AES_TAG); try { mCipher = Cipher.getInstance(TRANSFORMATION_STR); } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } } public static synchronized Encryption getInstance() { if (sInstance == null) { sInstance = new Encryption(); } return sInstance; } public String encryptString(String strPwd) { String strToEncripted = null; strToEncripted = strPwd; String result = null; byte[] input = null; byte[] cipherText = null; int ctLength = 0; try { input = strToEncripted.getBytes(UTF8_STR); mCipher.init(Cipher.ENCRYPT_MODE, mKey, mParamSpec); cipherText = new byte[mCipher.getOutputSize(input.length)]; ctLength = mCipher.update(input, 0, input.length, cipherText, 0); ctLength += mCipher.doFinal(cipherText, ctLength); result = Base64.encodeToString(cipherText, Base64.DEFAULT) .replace(NEWLINE_CHAR, EMPTY_CHAR).trim(); } catch (InvalidKeyException e) { } catch (UnsupportedEncodingException e) { } catch (InvalidAlgorithmParameterException e) { } catch (ShortBufferException e) { } catch (IllegalBlockSizeException e) { } catch (BadPaddingException e) { } catch (IllegalStateException e) { } return result; } public String decryptstring(byte[] encripted) { String textDecrypt = ""; byte[] encriptedByteDecode64 = Base64.decode(encripted, Base64.DEFAULT); byte[] plainText = new byte[mCipher.getOutputSize(encriptedByteDecode64.length)]; int ptLength = 0; try { mCipher.init(Cipher.DECRYPT_MODE, mKey, mParamSpec); ptLength = mCipher.update(encriptedByteDecode64, 0, encriptedByteDecode64.length, plainText, 0); ptLength += mCipher.doFinal(plainText, ptLength); textDecrypt = (new String(plainText)).trim(); } catch (InvalidKeyException e) { } catch (InvalidAlgorithmParameterException e) { } catch (ShortBufferException e) { } catch (IllegalBlockSizeException e) { } catch (BadPaddingException e) { } return textDecrypt; } private String getMD5(String strKey) { String key = strKey; String result = null; try { MessageDigest algorithm = MessageDigest.getInstance(MD5_TAG); algorithm.reset(); algorithm.update(key.getBytes(UTF8_STR)); byte messageDigest[] = algorithm.digest(); StringBuilder hexString = new StringBuilder(); for (int count = 0; count < messageDigest.length; count++) { String hexaDecimal = Integer.toHexString(0xFF & messageDigest[count]); while (hexaDecimal.length() < 2) hexaDecimal = new StringBuilder(ZERO_STR).append(hexaDecimal).toString(); hexString.append(hexaDecimal); } result = hexString.toString(); } catch (NoSuchAlgorithmException e) { } catch (UnsupportedEncodingException e) { } return result; } } 

Usando la instancia singleton, el cifrado y descifrado de la cadena se implementan y ellos están trabajando principalmente.

A veces, aunque el cifrado ha sido inicializado, sigue lanzando una Excepción: java.lang.IllegalStateException: Cipher not initialized

El escenario es sobre todo cuando después de algún intervalo de tiempo (30 minutos), se realiza un descifrado de cadena.

¿Puede ser debido al uso incorrecto de la instancia Singleton?

En lugar de clase Singleton, he intentado cifrar la cadena creando una instancia de la clase Encryption utilizando el nuevo operador, pero el problema es que necesito el mismo objeto para el descifrado, de lo contrario java.lang.IllegalStateException: Cipher not initialized es lanzado.

Cualquier sugerencia / sugerencias son bienvenidas.

Este problema está destinado a ocurrir en un entorno multihilo, como me sucedió. El problema es un choque entre los métodos mCipher.init () y mCipher.doFinal ().

Los siguientes son los métodos relacionados en la clase Cipher:

 public final void init(int opmode, Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { init(opmode, key, params, JceSecurity.RANDOM); } public final void init(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { initialized = false; checkOpmode(opmode); if (spi != null) { checkCryptoPerm(spi, key, params); spi.engineInit(opmode, key, params, random); } else { chooseProvider(I_PARAMSPEC, opmode, key, params, null, random); } initialized = true; this.opmode = opmode; } public final int doFinal(byte[] output, int outputOffset) throws IllegalBlockSizeException, ShortBufferException, BadPaddingException { checkCipherState(); // Input sanity check if ((output == null) || (outputOffset < 0)) { throw new IllegalArgumentException("Bad arguments"); } chooseFirstProvider(); return spi.engineDoFinal(null, 0, 0, output, outputOffset); } private void checkCipherState() { if (!(this instanceof NullCipher)) { if (!initialized) { throw new IllegalStateException("Cipher not initialized"); } if ((opmode != Cipher.ENCRYPT_MODE) && (opmode != Cipher.DECRYPT_MODE)) { throw new IllegalStateException("Cipher not initialized " + "for encryption/decryption"); } } } 

Consulte el comportamiento de la variable initialized en un entorno multihebra con dos subprocesos ejecutando init () y doFinal (). La excepción devuelta no está relacionada con que el objeto no se haya inicializado realmente, sino que la variable initialized esté establecida en false .

Solucioné mi problema sincronizando mis métodos encryptString () y decryptString (). Espero que puedas obtener alguna información a través del código Cipher.

Tuve el mismo problema ( Cipher not initialized ). Yo estaba usando cifrado alto y, para mí, la solución estaba reemplazando los jarros de política normales en jre/lib/security con las versiones de fuerza ilimitada.

En su método decryptstring , usted llama

 byte[] plainText = new byte[mCipher.getOutputSize(encriptedByteDecode64.length)]; 

Unas pocas líneas antes de llamar

 mCipher.init(Cipher.DECRYPT_MODE, mKey, mParamSpec); 

Dado que el cifrado no se inicializa aún cuando llama a getOutputSize, obtendrá la excepción. Reordenar estas líneas debe arreglarlo. (Lo hizo por mí.)

  • Tiene algunos problemas con el archivo xml. Androide. Eclipse. Error: Invalid start tag PreferenceScreen
  • ¿Qué es un apkLIB y cómo uso uno?
  • Android: transmisión de audio a través de sockets TCP
  • Difusión cuando se captura la captura de pantalla en Android 4.0?
  • Android - getTabHost () no está definido
  • Diseño de código adecuado para Android / Java
  • La mejor manera de ejecutar el método asincrónicamente en Android (compacto y correcto)
  • Forzar subclases para establecer una variable en java
  • Cómo hacer una copia de un archivo en android?
  • Mapa de bits de Android: convierte píxeles transparentes a un color
  • Erro de Xalan.jar al crear un proyecto android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.