Golang 미디어위키 패스워드 해시

Jmnote (토론 | 기여)님의 2022년 4월 29일 (금) 21:38 판 (→‎같이 보기)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)

1 개요[ | ]

Golang 미디어위키 패스워드 해시
package main

import (
	"crypto/rand"
	"crypto/sha512"
	"encoding/base64"
	"fmt"
	"strconv"
	"strings"

	"golang.org/x/crypto/pbkdf2"
)

func HashPassword(plain string) string {
	salt := make([]byte, 8)
	rand.Read(salt)
	hashed, err := hashPBKDF2_SHA512(plain, "30000", "64", base64.StdEncoding.EncodeToString(salt))
	if err != nil {
		return ""
	}
	return hashed
}

func hashPBKDF2_SHA512(plain string, iter string, keyLen string, salt string) (string, error) {
	iterNum, err := strconv.Atoi(iter)
	if err != nil {
		return "", err
	}
	keyLenNum, err := strconv.Atoi(keyLen)
	if err != nil {
		return "", err
	}
	salt2, err := base64.StdEncoding.DecodeString(salt)
	if err != nil {
		return "", err
	}
	k := pbkdf2.Key([]byte(plain), salt2, iterNum, keyLenNum, sha512.New)
	return ":pbkdf2:sha512:" + iter + ":" + keyLen + ":" + salt + ":" + base64.StdEncoding.EncodeToString(k), nil
}

func CheckPassword(plain string, hashed string) bool {
	parts := strings.Split(hashed, ":")
	if len(parts) < 7 {
		return false
	}
	hashed2, err := hashPBKDF2_SHA512(plain, parts[3], parts[4], parts[5])
	if err != nil {
		return false
	}
	return hashed == hashed2
}

func main() {
	// test CheckPassword()
	hashed1 := ":pbkdf2:sha512:30000:64:M3SogtWf2lWrZyFaWgkwOQ==:UE9RMErT6Qn6wKMJ48h7yKN2/UH2DiYh5DswfapYJAOJ0iPIOyjJRK+bs5dBFdUm2KgpPr/0D+vdSMy4QuearA=="
	hashed2 := ":pbkdf2:sha512:30000:64:mdp3c8sQtHFyBPM1KGvEkQ==:j8LofQ98Y88zDmilkpeV4wBPhE65Wj6lb9LJ0o/ZHK4m8cFoKs0BN10m6PbTXcnb/MOGBiPBZ/+dQGAQ3DcIAA=="
	hashed3 := ":pbkdf2:sha512:30000:64:vPkzf0QCNGCie/RATXixvg==:IXC3XtUd8EgYFQ+gfWuxwfhZI7/XwsPCsLm+73ktelQ1usKNbxp3WhgusWj/z7xtcoPpKIpr9JLP/I1mcy1h7A=="
	fmt.Println("== test CheckPassword() ==")
	fmt.Println(CheckPassword("passHello", hashed1)) // true
	fmt.Println(CheckPassword("passWorld", hashed2)) // true
	fmt.Println(CheckPassword("passWorld", hashed3)) // true

	// test HashPassword()
	fmt.Println("== test HashPassword() ==")
	fmt.Println(CheckPassword("lorem", HashPassword("lorem")))                 // true
	fmt.Println(CheckPassword("lorem", HashPassword("ipsum")))                 // false
	fmt.Println(CheckPassword("무궁화 꽃이 피었습니다.", HashPassword("무궁화 꽃이 피었습니다."))) // true
	fmt.Println(CheckPassword("무궁화 꽃이 피었습니다.", HashPassword("무궁화 꽃이 피었습니까?"))) // false
}

2 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}