开发者社区> 问答> 正文

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

django 默认密码加密算法 pbkdf2-sha256 如何用 java 实现
加密后的密码例如:
pbkdf2_sha256$15000$ZdYJKwuyheny$6pZJnPwX5wk6yGOtNFrz4nu3ePtkdURtmqiXwI/agFM=
怎么用 java 实现呢?

展开
收起
OSC开源社区 2024-05-31 15:47:24 53 0
1 条回答
写回答
取消 提交回答
  • 网上找了几个语言的pbkdf2_sha256算法,计算出的结果都和python不一样。

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

    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 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 = byte(block >> 24)
      buf = byte(block >> 16)
      buf = byte(block >> 8)
      buf = 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, "")
    }
    
    2024-05-31 16:37:29
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
\"视频服务特色解决方案——直播连麦与点播加密 \" 立即下载
从《阿里巴巴Java开发手册》编写推广谈技术成长 立即下载
量子加密通信技术 立即下载