之前Web业务框架是基于Python的Django。已有一定用户量,现需要集成和解析之前的密码规则。进而再逐步替换用户密码。
Django框架自带密码生成是基于pbkdf2_sha256加密方式的,有一点不同的是。
他是基于4个字符串值合并的集合。
哈希算法+算法迭代次数(工作因子)+随机Salt+最终的密码哈希值。
<algorithm>$<iterations>$<salt>$<hash>
具体的实现可以参考文后的Django中的密码管理。
以下的代码可以优化为自定义的iterations,slat值,看你们操作了 :)
package com.demo.utils
/**
* @author watson haw
* @date 2021/5/24 2:07 下午
* 将密码转换为Django的pbkdf2_sha256
*/
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import kotlin.system.exitProcess
class HashHelper {
val DEFAULT_ITERATIONS: Int = 10000;
val algorithm: String = "pbkdf2_sha256";
fun getEncodeHash(password: String, salt: String, iterations: Int): String {
lateinit var keyFactory: SecretKeyFactory;
try {
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
} catch (e: InvalidKeySpecException) {
println("Could NOT retrieve PBKDF2WithHmacSHA256 algorithm")
exitProcess(1)
}
val keySpec: KeySpec = PBEKeySpec(
password.toCharArray(),
salt.toByteArray(),
iterations,
256
)
lateinit var secret: SecretKey;
try {
secret = keyFactory.generateSecret(keySpec)
} catch (e: InvalidKeySpecException) {
println("Could NOT generate secret key");
e.printStackTrace()
}
val rawHash: ByteArray = secret.encoded
val hashBase64: ByteArray = Base64.getEncoder().encode(rawHash)
return String(hashBase64)
}
fun encode(password: String, salt: String, iterations: Int = DEFAULT_ITERATIONS): String {
val hash: String = getEncodeHash(password, salt, iterations)
return "%s$%d$%s$%s".format(algorithm, iterations, salt, hash)
}
fun checkPassword(password: String, hashedPassword: String): Boolean {
val parts: List<String> = hashedPassword.split("$")
if (parts.size != 4) return false
val iterations: Int = parts[1].toInt()
val salt = parts[2]
val hash = encode(password, salt, iterations)
return hash == hashedPassword
}
}
复制代码
Spring Boot测试代码
package com.demo.utils
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
/**
* @author watson haw
* @date 2021/5/24 3:32 下午
*/
@SpringBootTest
class HashHelperTests {
@Test
fun testCheckPassword() {
val hasHelper = HashHelper()
val passWord = "mystery"
val hashPassword = "pbkdf2_sha256\$10000\$qx1ec0f4lu4l\$3G81rAm/4ng0tCCPTrx2aWohq7ztDBfFYczGNoUtiKQ="
Assertions.assertTrue(hasHelper.checkPassword(passWord, hashPassword))
}
@Test
fun testEncode() {
val hashHelper = HashHelper()
val password = "123456"
val salt = "you_salt"
val hashResult = hashHelper.encode(password, salt)
Assertions.assertEquals(
"pbkdf2_sha256\$10000\$you_salt\$VgKivkVxt2f+KKdosZAeGsO90GHXV5nXsOyOOjOy3mY=",
hashResult
)
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END