사이드프로젝트로 출시한 앱 테스트중 동일한 제목으로 컨텐츠를 생성하면 새로 생성한 이미지로 기존에 동일한 제목의 컨텐츠들의 이미지가 변경되는 현상을 발견했다.
해당 원인을 찾아보니 이미지 업로드시 컨텐츠 제목으로 이미지 이름을 보내고 있었고, 심지어 파일 이름을 해싱하는 로직은 MD5 알고리즘 방식이였다.. 따라서 동일한 제목으로 등록하니 동일한 암호화 값이 계속 출력되게 되었고 문제가 발생한 것 이다.
이를 해결하기 MD5 대신 SHA256에 salt를 첨가하기로 결정했다.
기존 MD5 적용 코드는 다음과 같다.
private fun createRandomFileName(fileName: String): String {
val ext = getFileExtension(fileName)
try {
val md5 = MessageDigest.getInstance("MD5")
md5.update(fileName.toByteArray(Charsets.UTF_8))
val md5Hash = md5.digest()
var stringBuilder = StringBuilder()
for (b in md5Hash) {
val hexStr = String.format("%02x", b)
stringBuilder.append(hexStr)
}
return stringBuilder.toString() + "." + ext
} catch (e: Exception) {
log.error("fail to create random name {}", e)
throw CustomException(CustomErrorCode.UNDEFINED_ERROR)
}
}
이를 SHA256에 random salt를 첨가하는 방식으로 변경했다.
private fun createRandomFileName(fileName: String): String {
val ext = getFileExtension(fileName)
try {
// create salt
val secureRandom = SecureRandom()
val salt = ByteArray(16)
secureRandom.nextBytes(salt)
// sha 256
val sha256 = MessageDigest.getInstance("SHA-256")
// add salt to hash
sha256.update(salt)
val hash = sha256.digest(fileName.toByteArray(Charsets.UTF_8))
var stringBuilder = StringBuilder()
for (b in hash) {
val hexStr = String.format("%02x", b)
stringBuilder.append(hexStr)
}
return stringBuilder.toString() + "." + ext
} catch (e: Exception) {
log.error("fail to create random name {}", e)
throw CustomException(CustomErrorCode.UNDEFINED_ERROR)
}
}