I am trying to store encrypted data in a SQL database using AES with Initialization Vector (IV). I am able to do this with the following class:
class Encrypted (wordE : String) {
val keyGenerator: KeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,"AndroidKeyStore")
val keyGenParameterSpec = KeyGenParameterSpec.Builder("MyKeyAlias",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
fun genKey(){
keyGenerator.init(keyGenParameterSpec)
keyGenerator.generateKey()
}
fun getKey(): SecretKey {
genKey()
val keystore = KeyStore.getInstance("AndroidKeyStore")
keystore.load(null)
val secretKeyEntry = keystore.getEntry("MyKeyAlias", null) as KeyStore.SecretKeyEntry
return secretKeyEntry.secretKey
}
fun encryptData(data: String): Pair<ByteArray, ByteArray> {
val cipher = Cipher.getInstance("AES/CBC/NoPadding")
var temp = data
while (temp.toByteArray(Charsets.UTF_8).size % 16 != 0)
temp += "\u0020"
cipher.init(Cipher.ENCRYPT_MODE, getKey())
val ivBytes = cipher.iv
val encryptedBytes = cipher.doFinal(temp.toByteArray(Charsets.UTF_8))
return Pair(ivBytes, encryptedBytes)
}
val pair = encryptData(wordE)
val encrypted = pair.second.toString(Charsets.UTF_8)
val iv = pair.first
}
but I have some problems to decrypt the data from the database. For decryption I have implemented another class:
class Decrypted (dataD: String, ivD :String) {
fun getKey(): SecretKey {
val keystore = KeyStore.getInstance("AndroidKeyStore")
keystore.load(null)
val secretKeyEntry = keystore.getEntry("MyKeyAlias", null) as KeyStore.SecretKeyEntry
return secretKeyEntry.secretKey
}
fun decryptData(data: String, iv : String) : String {
val spec = IvParameterSpec(iv.toByteArray())
val decipher = Cipher.getInstance("AES/CBC/NoPadding")
decipher.init(Cipher.DECRYPT_MODE, getKey(), spec)
val encryptedData: ByteArray = data.toByteArray()
return decipher.doFinal(encryptedData).toString().trim()
}
val decryptedData = decryptData(dataD, ivD)
}
I understood that IV must be the same as the one generated during encryption, so I also stored IV in the database as .
From my logcat I get an "InvocationTargetException" to "Invalid IV" message. I can see that when I call the Decrypted class enter for decryption:
dataEncrypted: /�,@�j3�RqLrY�
iv_stored: [B@5a36422