goパスワードhash暗号化

5162 ワード

目次
  • bcrypt暗号化アルゴリズムの原理と応用
  • 単純使用
  • とともにdemo
  • を実現する
  • ユーザが入力パスワード
  • を取得する.
  • Hash&Saltユーザーのパスワード
  • 現在私たちは何をしていますか
  • 認証パスワード
  • Main関数
  • を更新
  • 全コード
  • bcrypt暗号化アルゴリズムの原理と応用
    同じパスワードでは、生成されるたびにhashは異なるが、hashにはsalt(hash生成プロセス:saltをランダムに生成し、saltはpasswordとhashを行う)が含まれている.次回の検査時にhashからsaltを取り出し、saltはpasswordとhashを行う.得られた結果をDBに保存したhashと比較する
    単純な使用
    package main
    
    import (
    	"fmt"
    	"log"
    	"golang.org/x/crypto/bcrypt"
    )
    
    func main() {
    	hash := hashAndSalt([]byte("123"))
    	fmt.Println("hash    ", hash)
    	pwdMatch := comparePasswords(hash, []byte("123"))
    	if pwdMatch {
    		fmt.Println("      ")
    	}
    }
    
    //     
    func hashAndSalt(pwd []byte) string {
    	hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
    	if err != nil {
    		log.Println(err)
    	}
    	return string(hash)
    }
    
    //     
    func comparePasswords(hashedPwd string, plainPwd []byte) bool {
    	byteHash := []byte(hashedPwd)
    
    	err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)
    	if err != nil {
    		log.Println(err)
    		return false
    	}
    	return true
    }
    

    実行後の結果
    D:\go_test>go run hash.go
    hash     $2a$04$VQe0TCnCRWfB4O51Qflpses5l0udTyq74V3dNfibc1AT1JJck4S8u
          
    

    一緒にdemoを実現する
    この例では、ユーザーが入力したパスワードを取得し、saltハッシュ値を生成する方法を示すコンソールアプリケーションを作成します.この操作が完了すると、パスワードとハッシュ・バージョンを比較して、パスワードが正しいかどうかを確認します.
    ユーザーが入力したパスワードの取得
    まず、コンソールでユーザー入力を読み取る方法を作成します.
    func getPwd() []byte {
        fmt.Println("Enter a password")
        var pwd string
    
        //       
        _, err := fmt.Scan(&pwd)
        if err != nil {
            log.Println(err)
        }
        return []byte(pwd)
    
    }
    

    Hash&Saltユーザーのパスワード
    これで、Goのbcryptパケットから提供されるGenerateFromPassword(password []byte, cost int)([]byte, error)メソッドを使用して、ユーザーのパスワードをhashおよびsaltで暗号化することができます.
    GenerateFromPasswordメソッドは、指定されたcost値でパスワードのBcryptアルゴリズムのHash値を返します.提供されるcost値がMincostより小さい場合、GenerateFromPassword関数を使用する代わりにDefaultCostを使用する利点は、Saltを自動的に生成するために関数を作成する必要がないことです.
    次の関数は、GenerateFromPasswordを使用してsaltedハッシュ値を生成し、このハッシュ値はバイトスライスとして返される.その後、バイトスライスを文字列として返し、saltedハッシュをデータベースにユーザーパスワードとして格納できます.
    func hashAndSalt(pwd []byte) string {
        hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
        if err != nil {
            log.Println(err)
        }
        return string(hash)
    }
    

    今私たちは何をしましたか?
    これまで,コンソールからのユーザ入力を受け入れ,バイトスライスとして返す関数を作成してきた.次に、ユーザ入力を受信してsaltedハッシュ値を返す関数を作成します.次はコード事例です.
    package main
    
    import (
        "fmt"
        "log"
        "golang.org/x/crypto/bcrypt"
    )
    
    func main() {
       for {
            pwd := getPwd()
            hash := hashAndSalt(pwd)
            fmt.Println("Salted Hash", pwd)
         }
    }
    

    上のコードを実行すると、次の結果が得られます.
    > $ Enter a password
    > $ foobar
    > Salted Hash $2a$10$...........
    

    ここで注意しなければならないのは、強制的に停止するまでforループ呼び出し関数を使用することです.GOに慣れていない人にとって、これは他の言語のwhile{}と同じ効果です.
    パスワードの検証
    最後に、パスワードの正確性を検証してシステムにログインする必要があります.bcryptパッケージが提供するCompareHashAndPassword(hashedPassword, password []byte) error関数を使用することができます.
    CompareHashAndPasswordは、bcryptハッシュパスワードを純粋なテキストと比較します.成功したらnilを返し、失敗したらエラーを返します.CompareHashAndPassword関数を使用してbool値を返す別の関数を作成し、パスワードが一致しているかどうかを確認します.
    func comparePasswords(hashedPwd string, plainPwd []byte) bool {
    
        byteHash := []byte(hashedPwd)
        err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)\
        if err != nil {
            log.Println(err)
            return false
        }
        return true
    }
    

    Main関数の更新
    私たちは今、私たちの主な機能を更新することができて、パスワードを入力して、その塩漬けハッシュを取得して、それから再びパスワードを入力して、私たちの2番目のパスワードが私たちが入力した最初のパスワードと一致しているかどうかを明らかにすることができます.main関数を変更し、パスワードを入力するとsaltedハッシュ値を取得し、パスワードを再度入力して、パスワードが一致しているかどうかを確認します.
    func main() {
        for {
            pwd := getPwd()
            hash := hashAndSalt(pwd)
            pwd2 := getPwd()
            pwdMatch := comparePasswords(hash, pwd2)
            fmt.Println("Passwords Match?", pwd)
        }
    }
    

    すべてのコード
    package main
    
    import (
        "fmt"
        "log"
        "golang.org/x/crypto/bcrypt"
    )
    
    func main() {
        for {
           //         hash  
            pwd := getPwd()
            hash := hashAndSalt(pwd)
           //         
            pwd2 := getPwd()
            pwdMatch := comparePasswords(hash, pwd2)
            fmt.Println("Passwords Match?", pwd)
        }
    }
    
    func getPwd() []byte {
        fmt.Println("Enter a password")
        var pwd string
        _, err := fmt.Scan(&pwd)
        if err != nil {
            log.Println(err)
        }
        return []byte(pwd)
    }
    
    func hashAndSalt(pwd []byte) string {
        hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
        if err != nil {
            log.Println(err)
        }
        return string(hash)
    }
    
    func comparePasswords(hashedPwd string, plainPwd []byte) bool {
        byteHash := []byte(hashedPwd)
    
        err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)
        if err != nil {
            log.Println(err)
            return false
        }
        return true
    }
    

    bcrypt