/* 인코딩, 디코딩 */
CryptoConverter.kt
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Component
import java.util.*
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import javax.persistence.AttributeConverter
import javax.persistence.Convert
@Convert
class CryptoConverter(
private val aes256Config: AES256Config
) : AttributeConverter<String, String> {
private val key = aes256Config.key
private val iv = aes256Config.iv
private val secretKeySpec = SecretKeySpec(key!!.toByteArray(), "AES")
private val ivParameterSpec = IvParameterSpec(iv!!.toByteArray())
// 인코딩
override fun convertToDatabaseColumn(payload: String): String? {
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
val encrypted = cipher.doFinal(payload.toByteArray(charset("UTF-8")))
return byteArrayToHex(encrypted)
}
// 디코딩
override fun convertToEntityAttribute(payload: String): String {
val bytesOfPayload = Base64.getDecoder().decode(payload)
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
val originMessage = cipher.doFinal(hexToByteArray(payload))
return String(originMessage)
}
// 헥사 -> 바이트
fun hexToByteArray(hex: String?): ByteArray? {
if (hex == null || hex.isEmpty()) {
return null
}
val ba = ByteArray(hex.length / 2)
for (i in ba.indices) {
ba[i] = hex.substring(2 * i, 2 * i + 2).toInt(16).toByte()
}
return ba
}
// 바이트 -> 헥사
fun byteArrayToHex(ba: ByteArray?): String? {
if (ba == null || ba.isEmpty()) {
return null
}
val sb = StringBuffer(ba.size * 2)
var hexNumber: String
for (x in ba.indices) {
hexNumber = "0" + Integer.toHexString(0xff and ba[x].toInt())
sb.append(hexNumber.substring(hexNumber.length - 2))
}
return sb.toString()
}
// application.yml 에서 key, iv 값 가져오기
@Component
@ConfigurationProperties(prefix = "aes256")
data class AES256Config(
var key: String?,
var iv : String?
)
}
application.yml
aes256:
key: "ghj76ytrf12345567tyuijhgfre8990098765435tg212346789hgf"
iv: "gh567cfvbn456iol"
/* 테스트 */
import com.test.CryptoConverter
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.TestConstructor
import org.springframework.test.context.TestPropertySource
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@EnableConfigurationProperties(CryptoConverter.AES256Config::class)
@TestPropertySource("classpath:application.yml")
@SpringBootTest(classes = [CryptoConverter::class])
class CryptoTest2 @Autowired constructor(
private val cryptoConverter: CryptoConverter,
val aeS256Config: CryptoConverter.AES256Config
){
@Test
fun `인코딩테스트`() {
println(aeS256Config.key)
println(aeS256Config.iv)
println(cryptoConverter.convertToDatabaseColumn("1234123412341234"))
}
@Test
fun `디코딩테스트`() {
println(cryptoConverter.convertToEntityAttribute("7faf598710b84257cbb6f6fca720ef4fb8be41640ab24df86ee152c8e97e1918"))
}
}