-
Notifications
You must be signed in to change notification settings - Fork 0
Kotlin
alex [dot] kramer [at] g_m_a_i_l [dot] com edited this page Oct 11, 2018
·
6 revisions
Use ECB for short payloads. Use CBC with an IV (initialization vector) for longer payloads.
import com.google.gson.Gson
import org.junit.Assert.assertEquals
import org.junit.Test
import java.util.*
import javax.crypto.*
import javax.crypto.spec.SecretKeySpec
class EncryptionTest {
data class Thingy(
val field1: String,
val field2: Double,
val field3: Long
)
private fun generateAesKey(): SecretKey {
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(256)
val secretKey = keyGen.generateKey()
return secretKey
}
private fun decodeAesKeyBase64(keyEncodedAsBase64: String): SecretKey {
val keyData = byteDataFromBase64(keyEncodedAsBase64)
return SecretKeySpec(keyData, 0, keyData.size, "AES")
}
private fun byteDataToBase64(data: ByteArray): String {
return Base64.getEncoder().encodeToString(data)
}
private fun byteDataFromBase64(base64Data: String): ByteArray {
return Base64.getDecoder().decode(base64Data)
}
private fun encryptToBase64Ciphertext(key: SecretKey, stringToEncrypt: String): String {
val aesCipher = Cipher.getInstance("AES/ECB/PKCS5PADDING")
aesCipher.init(Cipher.ENCRYPT_MODE, key)
val stringToEncryptBytes = stringToEncrypt.toByteArray()
val ciphertextBytes = aesCipher.doFinal(stringToEncryptBytes)
return byteDataToBase64(ciphertextBytes)
}
private fun decrypt(key: SecretKey, base64Ciphertext: String): String {
val cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, key)
val ciphertext = byteDataFromBase64(base64Ciphertext)
val decryptedBytes = cipher.doFinal(ciphertext)
return String(decryptedBytes)
}
@Test
fun `encrypt all the things`() {
val key = generateAesKey()
val thingy = Thingy("eleventeen", 3.14159, 42)
val thingyJson = Gson().toJson(thingy)
val thingyJsonCiphertextBase64 = encryptToBase64Ciphertext(key, thingyJson)
val encodedKeyBase64 = byteDataToBase64(key.getEncoded())
val decodedKey = decodeAesKeyBase64(encodedKeyBase64)
val decryptedThingyJson = decrypt(decodedKey, userDataJsonCiphertextBase64)
val deserializedThingy = Gson().fromJson(decryptedThingyJson, Thingy::class.java)
assertEquals(key, decodedKey)
assertEquals(decryptedThingyJson, thingyJson)
assertEquals(thingy, deserializedThingy)
println(deserializedThingy)
}
}