Skip to content

Instantly share code, notes, and snippets.

@shank03
Last active July 22, 2020 05:16
Show Gist options
  • Save shank03/403124164018982faa823bec599bb7d9 to your computer and use it in GitHub Desktop.
Save shank03/403124164018982faa823bec599bb7d9 to your computer and use it in GitHub Desktop.
A helper class for AES-256 encryption
/*
* Copyright (c) 2020, Shashank Verma <shashank.verma2002@gmail.com> [@shank03]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/
import kotlinx.coroutines.*
import java.nio.charset.StandardCharsets
import java.security.spec.KeySpec
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
/**
* AES Encryption Helper
*
* Simplifying the methods...
*/
object AESHelper {
/**
* KeySpec params
*/
// TODO: Your own params
private const val KEY_LENGTH = 0
private const val ITERATION = 0
/**
* Put your own SALT.
*/
// TODO: Your own salt
private val SALT = ""
/**
* Encrypting text
*
* @param key The unique user key for both encryption and decryption
* @param strToEncrypt Text to be encrypted
* @param onResult Block to be executed when onResult
*/
@JvmStatic
fun encrypt(key: String?, strToEncrypt: String, onResult: (data: String?, err: String?) -> Unit) {
getData(key, Cipher.ENCRYPT_MODE, strToEncrypt, onResult)
}
/**
* Decrypting text
*
* @param key The unique user key for both encryption and decryption
* @param strToDecrypt Text to be decrypted
* @param onResult Block to be executed when onResult
*/
@JvmStatic
fun decrypt(key: String?, strToDecrypt: String, onResult: (data: String?, err: String?) -> Unit) {
getData(key, Cipher.DECRYPT_MODE, strToDecrypt, onResult)
}
/**
* Getting the processed data
*
* @param cKey The unique user key for both encryption and decryption
* @param opMode Cipher mode -> Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
* @param string Text to be processed
* @param onResult Block to be executed when onResult
*/
private fun getData(cKey: String?, opMode: Int, string: String, onResult: (data: String?, err: String?) -> Unit) {
if (cKey == null) {
onResult(null, "Key is NULL !")
return
}
if (string.length < 6) {
onResult(null, "Length should be more than 6")
return
}
var output: String? = null
var err: String? = null
// Executing in background thread
CoroutineScope(Dispatchers.IO).launch {
try {
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
val spec: KeySpec = PBEKeySpec(cKey.toCharArray(), SALT.toByteArray(), ITERATION, KEY_LENGTH)
val key = factory.generateSecret(spec)
val secretKey = SecretKeySpec(key.encoded, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(opMode, secretKey, IvParameterSpec(byteArrayOf(6, 1, 9, 0, 3, 2, 6, 0, 0, 0, 2, 9, 4, 3, 0, 6)))
if (opMode == Cipher.ENCRYPT_MODE) {
output = Base64.getEncoder().encodeToString(cipher.doFinal(string.toByteArray(StandardCharsets.UTF_8)))
err = null
} else if (opMode == Cipher.DECRYPT_MODE) {
output = String(cipher.doFinal(Base64.getDecoder().decode(string)))
err = null
}
withContext(Dispatchers.Main) { onResult(output, err) }
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) { onResult(null, e.message) }
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment