우리는 카카오/구글 로그인을 통해서 사용자의 정보를 가져와 firestore에 저장해준다.
이 과정에서 사용자의 이름, 사용자의 이메일은 그대로 올라가게 된다면 보안상 문제가 발생한다는 말을 듣고 유저 정보를 암호화해서 올리기로 했다.
먼저 내가 사용한 암호화 알고리즘은 AES알고리즘이다. 이 대칭키 알고리즘을 사용한데는 이유가 있다.
AES는 현재 가장 강력한 대칭키 암호화 알고리즘중 하나이다. 128비트, 192비트, 256비트 키 길이를 지원하고 256비트 키 길이를 사용할때 매우 강력한 보안을 제공한다 해서 256비트 키 길이를 사용했다.
빠르고 효율적인 알고리즘이다. 이는 특히 소프트웨어 구현이 최적화 되어있어서 데이터를 빠르게 암호화 및 복호화 할 수 있다.
AES는 다양한 보안 커뮤니티와 전문가들에 의해 검증되었으며, 공격에 대한 강력한 내성을 보여준다고 한다. 이는 알고리즘이 안전하고 신뢰할 수 있다는 뜻이다.
위와 같은 이유로 AES 대칭키 알고리즘을 사용했다.
object Constants{
const val AES_KEY = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
// AES 암호화에 사용할 무작위로 생성된 256비트 키
//val AES_KEY: ByteArray = generateRandomAESKey()
//private fun generateRandomAESKey(): ByteArray {
//val keyGen = KeyGenerator.getInstance("AES")
//keyGen.init(256, SecureRandom())
//val secretKey: SecretKey = keyGen.generateKey()
//return secretKey.encoded
//}
// 대칭키 암호화 함수
fun encrypt(data: String, key: String): String {
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
val secretKeySpec = SecretKeySpec(key.toByteArray(), "AES") //SecretKeySpec클래스 사용해서 암호화 키 생성
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec) //객체를 암호화 모드로 초기화
val encryptedBytes = cipher.doFinal(data.toByteArray()) //주어진 데이터를 암호화, 바이트배열로 전환
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT) //Base64로 인코딩해서 문자열로 반환
}
// 대칭키 복호화 함수
fun decrypt(encryptedData: String, key: String): String {
val cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING")
val secretKeySpec = SecretKeySpec(key.toByteArray(), "AES")
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec)
val decryptedBytes = cipher.doFinal(Base64.decode(encryptedData, Base64.DEFAULT))
return String(decryptedBytes)
}
}
16비트, 32비트 키를 지정할수 있지만 32비트 키를 만들어주는게 더 보안상 좋다고해서 32비트 길이의 키로 만들어줬다.
지금 const val AES_KEY값은 32비트 길이로 만들어주면되고, 그 아래 주석처리되어있는 내용은 키값을 랜덤으로 만들어주는 함수이다. 이를 사용하지 못한 이유가 있다.
처음에 유저가 회원가입할때 랜덤 생성된 키값으로 암호화해서 firestore에 저장되는데, 유저가 다시 앱을 실행시키면 해당 키값으로 복호화를 해야하는데 또다시 랜덤으로 생성된 키값으로 복호화해서 가져와지는 문제때문에 사용하지 못했다.
이문제만 해결된다면 위 방식으로 사용해주는게 더 보안상 안전하다!
잘못된 내용.. velog 해당 내용에서 다시 수정된 함수를 다루고있다..