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]) 这行报错
THE END
二维码