django 默认密码加密算法pbkdf2-sha256如何用java实现

加密后的密码例如:

pbkdf2_sha256$15000$ZdYJKwuyheny$6pZJnPwX5wk6yGOtNFrz4nu3ePtkdURtmqiXwI/agFM=

怎么用java实现呢?

回答

package main

import (
    "crypto/sha256"
    "encoding/base64"
    "strconv"
	"crypto/hmac"
	"hash"
	"io"
    "net/http"
	"strings"
	"math/rand"
	"time"
	"fmt"
)

// djnago 的实现细节请参考 Python 和 djnago 文档:
// djnago.contrib.auth.hashers.make_password
// djnago.utils.crypto import pbkdf2
// hashlib.sha256
// base64
func main() {
	http.HandleFunc("/djnagopwd", gendjnagopwd)
	http.ListenAndServe(":7070", nil)
}

func gendjnagopwd(rw http.ResponseWriter, req *http.Request){
	req.ParseForm();
	attempted := req.FormValue("attempted");
	var temp = req.FormValue("salt");
	var salt []byte
	if temp != ""{
		salt = []byte (temp)  // 盐,是一个随机字符串,每一个用户都不一样
	}else{
		salt = []byte(genSalt())
	}
	fmt.Println("-----------------salt:::::  "+salt+"  ----------------");
	pwd := []byte(attempted) // 用户设置的原始密码
    iterations := 15000             // 加密算法的迭代次数,15000 次
    digest := sha256.New            // digest 算法,使用 sha256

    // 第一步:使用 pbkdf2 算法加密
    dk := Key(pwd, salt, iterations, 32, digest)

    // 第二步:Base64 
    str := base64.StdEncoding.EncodeToString(dk)
	// 第三步:组合加密算法、迭代次数、盐、密码和分割符号 "$"
	io.WriteString(rw, "pbkdf2_sha256" + "$" + strconv.FormatInt(int64(iterations), 10) + "$" + string(salt) + "$" + str);
}

func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
	prf := hmac.New(h, password)
	hashLen := prf.Size()
	numBlocks := (keyLen + hashLen - 1) / hashLen

	var buf [4]byte
	dk := make([]byte, 0, numBlocks*hashLen)
	U := make([]byte, hashLen)
	for block := 1; block <= numBlocks; block++ {
		// N.B.: || means concatenation, ^ means XOR
		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
		// U_1 = PRF(password, salt || uint(i))
		prf.Reset()
		prf.Write(salt)
		buf[0] = byte(block >> 24)
		buf[1] = byte(block >> 16)
		buf[2] = byte(block >> 8)
		buf[3] = byte(block)
		prf.Write(buf[:4])
		dk = prf.Sum(dk)
		T := dk[len(dk)-hashLen:]
		copy(U, T)

		// U_n = PRF(password, U_(n-1))
		for n := 2; n <= iter; n++ {
prf.Reset()
prf.Write(U)
U = U[:0]
U = prf.Sum(U)
for x := range U {
	T[x] ^= U[x]
}
		}
	}
	return dk[:keyLen]
}
/**
*生成随机字符
**/
func genSalt() string {
	length := 12
    rand.Seed(time.Now().UnixNano())
    rs := make([]string, length)
    for start := 0; start < length; start++ {
        t := rand.Intn(3)
        if t == 0 {
            rs = append(rs, strconv.Itoa(rand.Intn(10)))
        } else if t == 1 {
            rs = append(rs, string(rand.Intn(26)+65))
        } else {
            rs = append(rs, string(rand.Intn(26)+97))
        }
    }
    return strings.Join(rs, "")
}

已解决,网上找了几个语言的pbkdf2_sha256算法,计算出的结果都和python不一样。

试过php/java/nodejs/golang,最后只有golang结果和python一致,无奈只有用golang生成密码,java调用golang的http服务,下面贴出代码:

亲测可用

go1.13.4

./dango_password.go:69:16: cannot slice buf (type byte)

prf.Write(buf[:4]) 这行报错

以上是django 默认密码加密算法pbkdf2-sha256如何用java实现的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>