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.
- Agregue dependencia de tareas a la tarea de complemento existente en Gradle?
- Cómo convertir HashMap a json Array en android?
- Android: Llamar a Python Script (a través de SL4A) desde código Java
- MathML y Java
- Android - Hashtag en TextView
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.
- Cómo analizar datos de 2 URL diferentes mediante el método asyncTask
- En RxJava, cómo reintentar / reanudar en caso de error, en lugar de completar el observable
- Android reconocimiento de voz API.System siempre reconoce el idioma predeterminado
- Manejo de InterruptedException mientras espera una señal de salida (error en Android?)
- ¿Cuál es la mejor manera de mantener el adaptador como una clase interna de actividad o fuera?
- Error de Android: MultipartEntity, la solicitud enviada por el cliente fue sintácticamente incorrecta
- ¿Cómo determinar el número de tarjetas SIM en un dispositivo?
- ¿Cómo cambiar los espacios para subrayar y hacer la cadena de caracteres insensible?
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í.)
- Cargador de clases personalizado para android?
- Rellene TableLayout con android: layout_weight de forma programática