Created
March 25, 2019 08:00
-
-
Save sunnyone/4011c6ad65eb60e54d2500756371f4c2 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package jp.syginc.aqua.common.security | |
import org.springframework.security.crypto.password.PasswordEncoder | |
import org.springframework.security.crypto.util.EncodingUtils | |
import java.security.GeneralSecurityException | |
import java.util.Base64 | |
import javax.crypto.SecretKeyFactory | |
import javax.crypto.spec.PBEKeySpec | |
class AspNetIdentityV2PasswordEncoder : PasswordEncoder { | |
// Format: https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasher.cs#L18 | |
private val algorithm = "PBKDF2WithHmacSHA1" | |
private val saltLength = 128 | |
private val subkeyLength = 256 | |
private val iterationCount = 1000 | |
override fun encode(rawPassword: CharSequence?): String { | |
TODO("not implemented") | |
} | |
private fun decode(encodedBytes: String?): ByteArray { | |
return Base64.getDecoder().decode(encodedBytes) | |
} | |
private fun encode(rawPassword: CharSequence, salt: ByteArray): ByteArray { | |
try { | |
val spec = PBEKeySpec(rawPassword.toString().toCharArray(), salt, iterationCount, subkeyLength) | |
val skf = SecretKeyFactory.getInstance(algorithm) | |
return EncodingUtils.concatenate(salt, skf.generateSecret(spec).encoded) | |
} catch (e: GeneralSecurityException) { | |
throw IllegalStateException("Could not create hash", e) | |
} | |
} | |
override fun matches(rawPassword: CharSequence, encodedPassword: String?): Boolean { | |
val digestedWithVersion = decode(encodedPassword) | |
if (digestedWithVersion.size != (8 + saltLength + subkeyLength) / 8) { | |
throw IllegalArgumentException("Invalid hash length: " + digestedWithVersion.size) | |
} | |
val digested = digestedWithVersion.sliceArray(1 until digestedWithVersion.size) | |
val salt = digested.sliceArray(0 until (saltLength / 8)) | |
val newEncoded = encode(rawPassword, salt) | |
return digested.contentEquals(newEncoded) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment