tapo-decrypt-poc/src/main/java/Aes.kt

94 lines
3.5 KiB
Kotlin

import java.security.InvalidAlgorithmParameterException
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import javax.crypto.*
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
class Aes {
private lateinit var encryptCipher: Cipher
private lateinit var decryptCipher: Cipher
private val encryptLock = Any()
private val decryptLock = Any()
constructor() {
try {
val key = generateKey()
val seed = SecureRandom().generateSeed(16)
val iv = IvParameterSpec(seed)
encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
init(Cipher.ENCRYPT_MODE, key, iv)
}
decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
init(Cipher.DECRYPT_MODE, key, iv)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
constructor(keyArr: ByteArray, ivArr: ByteArray) {
try {
val key = SecretKeySpec(keyArr, "AES")
val iv = IvParameterSpec(ivArr)
encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
init(Cipher.ENCRYPT_MODE, key, iv)
}
decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
init(Cipher.DECRYPT_MODE, key, iv)
}
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
} catch (e: NoSuchPaddingException) {
e.printStackTrace()
} catch (e: InvalidKeyException) {
e.printStackTrace()
} catch (e: InvalidAlgorithmParameterException) {
e.printStackTrace()
}
}
@Throws(InvalidAlgorithmParameterException::class, InvalidKeyException::class)
fun setKeyAndIV(keySpec: ByteArray, ivSpec: ByteArray) {
val secretKeySpec = SecretKeySpec(keySpec, "AES")
val ivParameterSpec = IvParameterSpec(ivSpec)
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
}
@Throws(BadPaddingException::class, ShortBufferException::class, IllegalBlockSizeException::class)
fun decrypt(input: ByteArray, output: ByteArray, inputLen: Int): Int {
var ret: Int
synchronized(decryptLock) { ret = decryptCipher.doFinal(input, 0, inputLen, output) }
return ret
}
@Throws(BadPaddingException::class, IllegalBlockSizeException::class)
fun decrypt(input: ByteArray, inputLen: Int): ByteArray {
var output: ByteArray
synchronized(decryptLock) { output = decryptCipher.doFinal(input, 0, inputLen) }
return output
}
@Throws(BadPaddingException::class, IllegalBlockSizeException::class)
fun decrypt(input: ByteArray): ByteArray {
var output: ByteArray
synchronized(decryptLock) { output = decryptCipher.doFinal(input, 0, input.size) }
return output
}
@Throws(BadPaddingException::class, IllegalBlockSizeException::class)
fun encrypt(input: ByteArray): ByteArray {
var output: ByteArray
synchronized(encryptLock) { output = encryptCipher.doFinal(input, 0, input.size) }
return output
}
@Throws(NoSuchAlgorithmException::class)
private fun generateKey(): SecretKey {
val instance = KeyGenerator.getInstance("AES")
instance.init(128)
return instance.generateKey()
}
}