The previous Web business framework was Django based on Python. The existing password rules need to be integrated and parsed. Then gradually replace the user password.

The Django framework uses pbkDF2_sha256 encryption to generate passwords, with one difference. It is based on a combined set of four string values.

Hash algorithm + number of algorithm iterations (work factor) + random Salt+ final password hash.

$

$

$



For details, see Password Management in Django below.

The following code can be optimized to create customized iterations and slat values as you go through

package com.demo.utils

/ * * *@author watson haw
 * @date2021/5/24 2:07 PM * Convert password to Django's 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
    }
}
Copy the code

Spring Boot test code

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(a) {
        val hasHelper = HashHelper()
        val passWord = "mystery"
        val hashPassword = "pbkdf2_sha256\$10000\$qx1ec0f4lu4l\$3G81rAm/4ng0tCCPTrx2aWohq7ztDBfFYczGNoUtiKQ="
        Assertions.assertTrue(hasHelper.checkPassword(passWord, hashPassword))
    }

    @Test
    fun testEncode(a) {
        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
        )
    }

Copy the code

Reference Java source code

Password management in Django

Java implementation of Django’s PBKDF2PasswordHasher encryption algorithm