Golang 장고 패스워드 해시

Jmnote (토론 | 기여)님의 2022년 4월 25일 (월) 15:31 판 (Jmnote님이 Golang 장고 스타일 패스워드 해시 문서를 Golang 장고 패스워드 해시 문서로 이동했습니다)

1 개요

Golang 장고 스타일 패스워드 해시
  • django에서 기본으로 사용하는 "PBKDF2_SHA256" 알고리즘을 그대로 Go로 구현한 것
  • django에서 생성한 패스워드도 검사할 수 있다.
package main

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/subtle"
	"encoding/base64"
	"fmt"
	"strconv"
	"strings"

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

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

func hashPBKDF2_SHA256(plain string, iter string, salt string) string {
	iterNum, _ := strconv.Atoi(iter)
	k := pbkdf2.Key([]byte(plain), []byte(salt), iterNum, 32, sha256.New)
	return "pbkdf2_sha256$" + iter + "$" + salt + "$" + base64.StdEncoding.EncodeToString(k)
}

func CheckPassword(plain string, hash string) bool {
	parts := strings.Split(hash, "$")
	if len(parts) < 4 {
		return false
	}
	temp := hashPBKDF2_SHA256(plain, parts[1], parts[2])
	if subtle.ConstantTimeCompare([]byte(hash), []byte(temp)) == 0 {
		return false
	}
	return true
}

func main() {
	// test CheckPassword()
	fmt.Println("== test CheckPassword() ==")

	plain1 := "hello"
	plain2 := "world"
	plain3 := "world"

	hash1 := "pbkdf2_sha256$320000$K9aurUIKet6v64ny8xR0I3$4zOktDqylGgwGW1QqSKodL3U7k/RPP6/CjPquoTVxgk="
	hash2 := "pbkdf2_sha256$320000$7WFhjzUnOfP2v7Cmoqg4yC$2zc5Tmbz1FRA4Evkhu1vJ0eIwgP90/+xq+aoi/kTmqw="
	hash3 := "pbkdf2_sha256$320000$7qZtq132zBoOu2HjXPvNKC$RekQdYBEkFTazN4lfYNc0EFkIxgnJzw5ADhFu4ial18="

	fmt.Println(CheckPassword(plain1, hash1)) // true
	fmt.Println(CheckPassword(plain2, hash2)) // true
	fmt.Println(CheckPassword(plain3, hash3)) // true

	fmt.Println(CheckPassword("world", hash1)) // false
	fmt.Println(CheckPassword("hello", hash2)) // false
	fmt.Println(CheckPassword("hello", hash3)) // false

	// 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 같이 보기

3 참고

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