I've got Android code that encrypts/decrypts data. It was written over a year ago by another developer (who has since left) and has worked fine until very recently, when it started crashing with the following exception:
android.security.keystore.AndroidKeyStoreRSAPrivateKey cannot be cast to javax.crypto.SecretKey
This appears to only occur when upgrading the application and an existing key is already present. I ran a diff off the gradle files against the prior release (which works) and no frameworks/sdks have been updated.
The exception occurs in .build():
private fun getOrGenerateNewKeysetHandle(alias: String): KeysetHandle {
val keysetName = "${TINK_KEYSET_NAME}_$alias"
return AndroidKeysetManager.Builder()
.withSharedPref(reactApplicationContext, keysetName, PREF_FILE_NAME)
.withKeyTemplate(HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM)
.withMasterKeyUri(MASTER_KEY_URI)
.build()
.keysetHandle
}
I traced the code down to AndroidKeystoreAesGcm
and the exception occurs on assignment returned from getKey (which succeeds):
public AndroidKeystoreAesGcm(String keyId) throws GeneralSecurityException, IOException {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null /* param */);
key = (SecretKey) keyStore.getKey(keyId, null /* password */);
}
This has left me uncertain of how to proceed. KeyStore has a key and I need it to access application data. I suspect my old arch-nemesis, gradle, is to blame, but... well, any help or insight would be greatly appreciated.