Created
July 17, 2020 09:59
-
-
Save xmppjingle/b07d205088c4cc65937d0330aa2d4372 to your computer and use it in GitHub Desktop.
Kotlin PasswordUtils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.security.NoSuchAlgorithmException | |
import java.security.SecureRandom | |
import java.security.spec.InvalidKeySpecException | |
import java.util.* | |
import javax.crypto.SecretKeyFactory | |
import javax.crypto.spec.PBEKeySpec | |
class PasswordUtils { | |
companion object { | |
private val random: Random = SecureRandom() | |
fun generateSalt(length: Int, supportedChars: String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"): String = | |
StringBuilder(length).let { returnValue -> | |
for (i in 0 until length) { | |
returnValue.append(supportedChars[random.nextInt(supportedChars.length)]) | |
} | |
returnValue.toString() | |
} | |
private fun hash(password: CharArray, salt: ByteArray, iterations: Int, keyLength: Int): ByteArray { | |
val spec = PBEKeySpec(password, salt, iterations, keyLength) | |
Arrays.fill(password, Character.MIN_VALUE) | |
return try { | |
val skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") | |
skf.generateSecret(spec).encoded | |
} catch (e: NoSuchAlgorithmException) { | |
throw AssertionError("Error while hashing a password: " + e.message, e) | |
} catch (e: InvalidKeySpecException) { | |
throw AssertionError("Error while hashing a password: " + e.message, e) | |
} finally { | |
spec.clearPassword() | |
} | |
} | |
fun generateSecurePassword(password: String, salt: String, iterations: Int = 1000, keyLength: Int = 256): String = | |
hash(password.toCharArray(), salt.toByteArray(), iterations, keyLength).let { securePassword -> | |
Base64.getEncoder().encodeToString(securePassword) | |
} | |
fun verifyUserPassword(providedPassword: String, | |
securedPassword: String, salt: String): Boolean = | |
generateSecurePassword(providedPassword, salt).equals(securedPassword, ignoreCase = true) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment