title: Android KeyStore Encrypt and Decrypt Data
body: <p>My problem is this: I am trying to encrypt some user's sensitive data before save it into my Database. Encryption was not a problem, the problem begins in the decryption part.</p>
  
  <p>I got this:</p>
  
  <pre><code>07-22 16:25:38.941 18035-18035/io.nourish.strongerasfukk E/AndroidRuntime: FATAL EXCEPTION: main
  Process: io.nourish.strongerasfukk, PID: 18035
  java.lang.RuntimeException: Unable to start activity ComponentInfo{io.nourish.strongerasfukk/io.nourish.strongerasfukk.Register}: java.security.InvalidKeyException: Keystore operation failed
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520)
      at android.app.ActivityThread.-wrap11(ActivityThread.java)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:148)
      at android.app.ActivityThread.main(ActivityThread.java:5466)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
   Caused by: java.security.InvalidKeyException: Keystore operation failed
      at android.security.KeyStore.getInvalidKeyException(KeyStore.java:692)
      at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712)
      at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
      at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
      at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263)
      at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108)
      at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612)
      at javax.crypto.Cipher.tryCombinations(Cipher.java:532)
      at javax.crypto.Cipher.getSpi(Cipher.java:437)
      at javax.crypto.Cipher.init(Cipher.java:815)
      at javax.crypto.Cipher.init(Cipher.java:774)
      at **io.nourish.strongerasfukk.utilities.Encryption.decrypt(Encryption.kt:28)
      at io.nourish.strongerasfukk.Register.onCreate(Register.kt:54)**
      at android.app.Activity.performCreate(Activity.java:6251)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520) 
      at android.app.ActivityThread.-wrap11(ActivityThread.java) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:148) 
      at android.app.ActivityThread.main(ActivityThread.java:5466) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
   Caused by: android.security.KeyStoreException: Incompatible padding mode
      at android.security.KeyStore.getKeyStoreException(KeyStore.java:632)
      at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712) 
      at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54) 
      at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89) 
      at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263) 
      at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108) 
      at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612) 
      at javax.crypto.Cipher.tryCombinations(Cipher.java:532) 
      at javax.crypto.Cipher.getSpi(Cipher.java:437) 
      at javax.crypto.Cipher.init(Cipher.java:815) 
      at javax.crypto.Cipher.init(Cipher.java:774) 
      at io.nourish.strongerasfukk.utilities.Encryption.decrypt(Encryption.kt:28) 
      at io.nourish.strongerasfukk.Register.onCreate(Register.kt:54) 
      at android.app.Activity.performCreate(Activity.java:6251) 
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2520) 
      at android.app.ActivityThread.-wrap11(ActivityThread.java) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:148) 
      at android.app.ActivityThread.main(ActivityThread.java:5466) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
  </code></pre>
  
  <p>As you can see, the problem reference this two lines of code, which are:</p>
  
  <p>Encryption.kt (line 28)</p>
  
  <pre><code>cipher.init(Cipher.DECRYPT_MODE, key)
  </code></pre>
  
  <p>&amp;</p>
  
  <p>Register.kt (line 54)</p>
  
  <pre><code>var decryptedData = encryption.decrypt(encryptedData,masterKey?.private)
  </code></pre>
  
  <p>I've tried to put in the Cipher.init the provider or without the provider and got the same error; I've sought on the web or over here for some solutions but got nothing. What I am missing or doing wrong? Also, I tried the example over here (<a href="https://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/" rel="nofollow noreferrer">Link</a>) without any result as well.</p>
  
  <p>I got the code example from this link (<a href="https://proandroiddev.com/secure-data-in-android-encryption-in-android-part-2-991a89e55a23" rel="nofollow noreferrer">link</a>) but had to modify some things to my own purporses.</p>
  
  <p>Here is my code, for better understanding.</p>
  
  <p>KeyStoreAdapter.kt</p>
  
  <pre><code>class KeyStoreAdapter {
  
  private val kS = createAndroidKeyStore()
  
  fun checkIfKeyExists(key: String) {
      val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
      val alias = keyStore.aliases().toList()
  
      if(!alias.contains(key)) {
          val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
          val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder("MasterKeys", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
                  .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                  .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                  .build()
          kpg.initialize(parameterSpec)
          kpg.generateKeyPair()
      }
  }
  
  fun getKeys(alias: String): KeyPair? {
      val privateKey = kS.getKey(alias, null) as PrivateKey?
      val publicKey = kS.getCertificate(alias)?.publicKey
  
      return if(privateKey != null &amp;&amp; publicKey != null) {
          KeyPair(publicKey, privateKey)
      } else {
          null
      }
  }
  
  private fun createAndroidKeyStore(): KeyStore {
      val keyStore = KeyStore.getInstance("AndroidKeyStore")
      keyStore.load(null)
      return keyStore
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Encryption.kt
  class Encryption {</p>
  
  <pre><code>val cipher = Cipher.getInstance(Config.TRANSFORMATION)
  
  fun encrypt(data: String, key: Key?): String {
      cipher.init(Cipher.ENCRYPT_MODE, key)
      val bytes = cipher.doFinal(data.toByteArray())
      return Base64.encodeToString(bytes, Base64.DEFAULT)
  }
  
  fun decrypt(data: String, key: Key?): String {
      cipher.init(Cipher.DECRYPT_MODE, key)
      val encryptedData = Base64.decode(data, Base64.DEFAULT)
      val decodedData = cipher.doFinal(encryptedData)
      return String(decodedData)
  }
  </code></pre>
  
  <p>}</p>
  
  <pre><code>const val TRANSFORMATION = "RSA/ECB/PKCS1Padding"
  </code></pre>
  
  <p>Thanks in advance to everyone!</p>