Skip to content
  • Hash icon  Golang
  • 【技術メモ】Go言語でbcryptパスワードハッシュ化の実装方法

    Calendar icon Published:
    【技術メモ】Go言語でbcryptパスワードハッシュ化の実装方法

    bcrypt主要関数メモ

    ⚡ GenerateFromPassword

    func GenerateFromPassword(password []byte, cost int) ([]byte, error)
    • 入力:
      • password []byte → 平文パスワード
      • cost int → 計算コスト (4-31)
    • 出力:
      • ハッシュ値 + エラー
    • メモ:
      • パスワード長は最大72バイト
      • 低コスト指定時は自動的に10に引き上げ

    ⚡ CompareHashAndPassword

    func CompareHashAndPassword(hashedPassword, password []byte) error
    • 入力:
      • hashedPassword []byte → 保存済みハッシュ
      • password []byte → 検証したいパスワード
    • 出力:
      • 一致時 → nil
      • 不一致時 → エラー

    ⚡ コスト定数

    const (
        MinCost     int = 4  // 最小(非推奨)
        MaxCost     int = 31 // 最大(重い)
        DefaultCost int = 10 // 標準
    )

    サンプルコード集

    ✅ 最小限のハッシュ化実装

    // パスワードハッシュ化(最小実装)
    password := []byte("super-secret")
    hash, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)
    // → "$2a$10$..."

    ✅ パスワード検証(ログイン処理など)

    // 検証処理(最小実装)
    err := bcrypt.CompareHashAndPassword(hash, []byte("super-secret"))
    if err == nil {
        // 認証成功
    } else {
        // 認証失敗
    }

    ✅ ハイセキュリティ設定

    // セキュリティ重視(処理は遅くなる)
    hash, err := bcrypt.GenerateFromPassword(password, 14)

    ✅ 便利ユーティリティ関数

    // 文字列 → ハッシュ文字列 変換
    func HashPassword(password string) (string, error) {
        bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
        return string(bytes), err
    }
    
    // パスワード検証(true/false形式)
    func CheckPasswordHash(password, hash string) bool {
        err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
        return err == nil
    }

    実装例(認証システム)

    👤 ユーザー登録処理

    func RegisterUser(email, password string) error {
        // ハッシュ生成
        hashedPW, err := HashPassword(password)
        if err != nil {
            return fmt.Errorf("パスワードハッシュ化エラー: %w", err)
        }
    
        // DBに保存
        _, err = db.Exec(
            "INSERT INTO users (email, password_hash, created_at) VALUES (?, ?, NOW())",
            email, hashedPW
        )
        return err
    }

    🔐 ログイン認証処理

    func LoginUser(email, password string) (bool, error) {
        var hashedPW string
    
        // ハッシュ取得
        err := db.QueryRow(
            "SELECT password_hash FROM users WHERE email = ?",
            email
        ).Scan(&hashedPW)
    
        if err != nil {
            return false, err // ユーザーなし or DBエラー
        }
    
        // パスワード検証
        return CheckPasswordHash(password, hashedPW), nil
    }

    bcryptハッシュ構造

    $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
    \__/\__/\____________________/\_____________________________/
     |   |           |                          |
     |   |           |                          +-- 実際のハッシュ値
     |   |           |
     |   |           +-- ソルト (16バイト)
     |   |
     |   +-- コスト (10)
     |
     +-- ハッシュ種別 ($2a$ = bcrypt)

    重要メモ

    • DB設計: VARCHAR(60)以上で保存すること
    • 同一パスワード: 毎回異なるハッシュ生成(自動ソルト)
    • コスト増加: +1ごとにハッシュ時間約2倍に増加
    • セキュリティ: 最低コスト10以上を推奨(OWASP基準)
    • メモリ使用: 他ハッシュ関数より多め(考慮すべき)
    • 特徴: GPUによる総当たり攻撃に強い設計
    • 注意: Webサーバーではレスポンス時間への影響を考慮

    よくあるコード例

    JWT認証と組み合わせ

    // ユーザー認証後にJWTトークン発行
    func GenerateJWT(userID int) (string, error) {
        // ここにJWT生成コード
    }
    
    func LoginHandler(w http.ResponseWriter, r *http.Request) {
        // 認証処理
        success, _ := LoginUser(email, password)
        if success {
            token, _ := GenerateJWT(userID)
            // tokenをクライアントに返す
        }
    }

    パスワードリセット

    func ResetPassword(userID int, newPassword string) error {
        hashedPW, _ := HashPassword(newPassword)
        _, err := db.Exec("UPDATE users SET password_hash = ? WHERE id = ?",
            hashedPW, userID)
        return err
    }

    エラーハンドリング

    // よくあるエラーパターン
    switch {
    case errors.Is(err, bcrypt.ErrMismatchedHashAndPassword):
        // パスワード不一致
    case errors.Is(err, bcrypt.ErrHashTooShort):
        // ハッシュ形式不正
    default:
        // その他エラー
    }

    パフォーマンス比較

    コストハッシュ化時間セキュリティ
    10〜80ms標準
    12〜320ms
    14〜1.3s非常に高

    ※2.8GHz Intel Core i7での参考値

    参考情報

    • 2025年4月現在の最新パッケージ: golang.org/x/crypto/bcrypt
    • RESTful API実装で最も使われているハッシュアルゴリズム
    • マイクロサービスアーキテクチャでの標準的認証方式