👉 セキュアなWeb/APIサーバー実装、ユーザー認証システム、パスワード管理に必須のbcryptハッシュ化メモ。Golang、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:
// その他エラー
}
参考情報