Android Simple String Encryption (using own/static key)

Oct 6, 2019
class CipherHelper(val algorithm: String, val transformation: String, val iv: String? = null) {    companion object {        private const val ALGO_BLOWFISH = "Blowfish"        private const val ALGO_AES = "AES"        private const val ALGO_DES = "DES"        // iv length of 8        fun getBlowfishInstance(iv: String) = CipherHelper(ALGO_BLOWFISH, "Blowfish/CBC/PKCS5Padding", iv)        // iv length of 16        fun getAESInstance(iv: String) = CipherHelper(ALGO_AES, "AES/CBC/PKCS5Padding", iv)        // iv length is 8        fun getDESInstance(iv: String) = CipherHelper(ALGO_DES, "DES/CBC/PKCS5Padding", iv)    }    private val cipher by lazy { Cipher.getInstance(transformation)  }    fun getSecretKey(secret: String): SecretKeySpec {        val hash = when (algorithm) {            ALGO_DES -> {                val spec = DESKeySpec(secret.toByteArray())                val f = SecretKeyFactory.getInstance("DES")                f.generateSecret(spec).encoded            }            ALGO_AES -> {                val random = SecureRandom()                val salt = ByteArray(16)                random.nextBytes(salt)                val spec = PBEKeySpec(secret.toCharArray(), salt, 65536, 128)                val f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")                f.generateSecret(spec).encoded            }            else -> { // BLOWFISH                secret.toByteArray()            }        }        return SecretKeySpec(hash, algorithm)    }    fun encrypt(secret: SecretKey, value: String): String {        val iv = IvParameterSpec(iv?.toByteArray())        cipher.init(Cipher.ENCRYPT_MODE, secret, iv)        val data = cipher.doFinal(value.toByteArray())        return Base64.encodeToString(data, Base64.DEFAULT)    }    fun decrypt(secret: SecretKey, value: String): String {        val iv = IvParameterSpec(iv?.toByteArray())        cipher.init(Cipher.DECRYPT_MODE, secret, iv)        val data = Base64.decode( value, Base64.DEFAULT)        return String(cipher.doFinal(data))    }}

Usage

val iv = "c16(}Hhx"val cipher = CipherHelper.getBlowfishInstance(iv)val secretKey = cipher.getSecretKey("3hb1L0x7moZA7OWtmi_mHPtxwl2GNxIDkk7A7bPM-Xo")val value = "I am Desmond"val encryptedValue = cipher.encrypt(secretKey, value)val decryptedValue = cipher.decrypt(secretKey, encryptedValue)

This weakness with this method is a static secret key which could be easily exposed. For a dynamic/secure secret key which is stored security within the application (unique for each application) usually used for password and app data encryption, do explore Android Keystore or Tink.

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.