Files
tactical-server/src/main/kotlin/de/ruvnox/tactical/security/PasswordHash.kt
T
2026-06-14 07:53:29 +00:00

29 lines
1016 B
Kotlin

package de.ruvnox.tactical.security
import java.security.MessageDigest
import java.util.Base64
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.PBEKeySpec
object PasswordHash {
fun verify(password: String, storedHash: String?): Boolean {
if (storedHash.isNullOrBlank()) return false
val parts = storedHash.split("$")
if (parts.size != 4) return false
if (parts[0] != "pbkdf2_sha256") return false
val iterations = parts[1].toIntOrNull() ?: return false
val salt = runCatching { Base64.getDecoder().decode(parts[2]) }.getOrNull() ?: return false
val expected = runCatching { Base64.getDecoder().decode(parts[3]) }.getOrNull() ?: return false
val spec = PBEKeySpec(password.toCharArray(), salt, iterations, expected.size * 8)
val actual = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA256")
.generateSecret(spec)
.encoded
return MessageDigest.isEqual(expected, actual)
}
}