title: java.lang.IllegalStateException: Cipher not initialized
body: <p>I have implemented Encryption / Decryption in Android application.</p>
  
  <p>I have added an Encryption class which has been made a Singleton class.</p>
  
  <p>Part of the code as follows:</p>
  
  <pre><code>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 &lt; messageDigest.length; count++) {
                      String hexaDecimal = Integer.toHexString(0xFF &amp; messageDigest[count]);
                      while (hexaDecimal.length() &lt; 2)
                          hexaDecimal = new StringBuilder(ZERO_STR).append(hexaDecimal).toString();
                      hexString.append(hexaDecimal);
                  }
                  result = hexString.toString();
              } catch (NoSuchAlgorithmException e) {
              } catch (UnsupportedEncodingException e) {
              }
              return result;
          }
      }
  </code></pre>
  
  <p>Using the singleton instance , encryption &amp; decryption of string are implemented &amp; they are working mostly.</p>
  
  <p>Sometimes , though the cipher has been initialised , still its throwing an Exception: <strong><code>java.lang.IllegalStateException: Cipher not initialized</code></strong></p>
  
  <p>The scenario is mostly when after some time-interval (30 mins), a decryption of string is performed.</p>
  
  <p>Can it be due to the incorrect use of Singleton instance?</p>
  
  <p>Instead of Singleton class , I have tried to encrypt string creating an instance of Encryption class using the new operator , but the problem is I need the same object for decryption , else the <strong><code>java.lang.IllegalStateException: Cipher not initialized</code></strong> is thrown.</p>
  
  <p>Any suggestions / hints are welcome.</p>