skip to Main Content

The Android docs give the following snippet for how to encrypt a message in AES:

val plaintext: ByteArray = ...
val keygen = KeyGenerator.getInstance("AES")
keygen.init(256)
val key: SecretKey = keygen.generateKey()
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, key)
val ciphertext: ByteArray = cipher.doFinal(plaintext)
val iv: ByteArray = cipher.iv

I get this error when implementing this method:

Unresolved reference: Cipher

So it appears the ‘Cipher’ object isn’t native, however I have no way of knowing how to import it by following the Android docs. How do I set up my project to be able to use ‘Cipher’?

2

Answers


  1. I’m not sure if using that Cipher is necessary, and if the solution I’m providing is the best approach, but I was able to use AES for encryption and decryption using the following code for a text input, means a String:

    ENCRYPTION

    // text
    
    val aesEncrypt: AESEncrypt = AESEncrypt()
    val encryptedByteArray = aesEncrypt.encrypt(text)
    val baos_text = ByteArrayOutputStream()
    val oosText = ObjectOutputStream(baos_text)
    oosText.writeObject(encryptedByteArray)
    val encryptedText = String(android.util.Base64.encode(baos_text.toByteArray(), android.util.Base64.DEFAULT))
    
    // key
    
    val key = aesEncrypt.mySecretKey
    val baos = ByteArrayOutputStream()
    val oos = ObjectOutputStream(baos)
    oos.writeObject(key)
    val keyAsString = String(android.util.Base64.encode(baos.toByteArray(), android.util.Base64.DEFAULT))
    
    // initialisation vector
    
    val iv = aesEncrypt.myInitializationVector
    val baosIV = ByteArrayOutputStream()
    val oosIV = ObjectOutputStream(baosIV)
    oosIV.writeObject(iv)
    val initialisationVector = String(android.util.Base64.encode(baosIV.toByteArray(), android.util.Base64.DEFAULT))
    

    DECRYPTION

    You must save the key, initialisation vector, and the encrypted text in order to decrypt it back.

    val initialisationVector = ... // get from wherever you saved it, local db, firebase...
    
    val bytesIV = android.util.Base64.decode(iv, android.util.Base64.DEFAULT)
    val oisIV = ObjectInputStream(ByteArrayInputStream(bytesIV))
    val initializationVectorIV = oisIV.readObject() as ByteArray
    
    
    val encryptedText = ... // get 
    
    val bytesText = android.util.Base64.decode(encryptedText, android.util.Base64.DEFAULT)
    val oisText = ObjectInputStream(ByteArrayInputStream(bytesText))
    val textByteArray = oisText.readObject() as ByteArray
    
    
    val key = ... // get your key
    val bytesKey = android.util.Base64.decode(key, android.util.Base64.DEFAULT)
    val oisKey = ObjectInputStream(ByteArrayInputStream(bytesKey))
    val secretKeyObj = oisKey.readObject() as SecretKey
    
    
    val aesDecrypt = AESDecrypt(secretKeyObj,initializationVectorIV)
    val decryptedByteArray = aesDecrypt.decrypt(textByteArray)
    
    val textAfterDecryption = decryptedByteArray.toString(charset("UTF-8"))
    

    EDIT

    AES helper class:

    import javax.crypto.Cipher
    import javax.crypto.KeyGenerator
    import javax.crypto.SecretKey
    
    class AESEncrypt {
    
        var mySecretKey: SecretKey? = null
        var myInitializationVector: ByteArray? = null
    
        fun encrypt(strToEncrypt: String): ByteArray {
    
            val plainText = strToEncrypt.toByteArray(Charsets.UTF_8)
            val keygen = KeyGenerator.getInstance("AES")
            keygen.init(256)
    
            val key = keygen.generateKey()
            mySecretKey = key
    
            val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
            cipher.init(Cipher.ENCRYPT_MODE, key)
            val cipherText = cipher.doFinal(plainText)
            myInitializationVector = cipher.iv
    
            return cipherText
        }
    
    }
    

    AES decrypt helper

    import javax.crypto.Cipher
    import javax.crypto.SecretKey
    import javax.crypto.spec.IvParameterSpec
    
    class AESDecrypt(private val mySecretKey: SecretKey?, private val initializationVector: ByteArray?) {
    
        fun decrypt(dataToDecrypt: ByteArray): ByteArray {
            val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
            val ivSpec = IvParameterSpec(initializationVector)
            cipher.init(Cipher.DECRYPT_MODE, mySecretKey, ivSpec)
            val cipherText = cipher.doFinal(dataToDecrypt)
    
            return cipherText
        }
    
    }
    

    Do tell if you still need any help 🙂

    Login or Signup to reply.
  2. javax.crypto.Cipher is part of the JCE and should be available. Does an import javax.crypto.Cipher not work? Then maybe something is wrong with your environment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search