2025-09-20 07:35:50 +00:00
|
|
|
// Package crypto provides cryptographic utilities for password hashing and verification.
|
2025-05-03 09:27:53 +00:00
|
|
|
package crypto
|
|
|
|
|
|
|
|
|
|
import (
|
2026-06-03 20:57:50 +00:00
|
|
|
"crypto/sha256"
|
|
|
|
|
"encoding/hex"
|
|
|
|
|
|
2025-05-03 09:27:53 +00:00
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
|
)
|
|
|
|
|
|
2025-09-20 07:35:50 +00:00
|
|
|
// HashPasswordAsBcrypt generates a bcrypt hash of the given password.
|
2025-05-03 09:27:53 +00:00
|
|
|
func HashPasswordAsBcrypt(password string) (string, error) {
|
|
|
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
|
|
|
return string(hash), err
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-20 07:35:50 +00:00
|
|
|
// CheckPasswordHash verifies if the given password matches the bcrypt hash.
|
2025-05-03 09:27:53 +00:00
|
|
|
func CheckPasswordHash(hash, password string) bool {
|
2026-01-05 04:54:56 +00:00
|
|
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
|
2025-05-03 09:27:53 +00:00
|
|
|
}
|
2026-06-01 18:48:12 +00:00
|
|
|
|
|
|
|
|
func IsHashed(s string) bool {
|
|
|
|
|
_, err := bcrypt.Cost([]byte(s))
|
|
|
|
|
return err == nil
|
|
|
|
|
}
|
2026-06-03 20:57:50 +00:00
|
|
|
|
|
|
|
|
// HashTokenSHA256 returns the hex-encoded SHA-256 digest of token. API tokens
|
|
|
|
|
// are high-entropy random strings, so a fast unsalted digest is sufficient to
|
|
|
|
|
// keep them irrecoverable at rest while allowing constant-time verification.
|
|
|
|
|
func HashTokenSHA256(token string) string {
|
|
|
|
|
sum := sha256.Sum256([]byte(token))
|
|
|
|
|
return hex.EncodeToString(sum[:])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsSHA256Hex reports whether s looks like a hex-encoded SHA-256 digest
|
|
|
|
|
// (64 lowercase hex characters), used to skip already-hashed token rows.
|
|
|
|
|
func IsSHA256Hex(s string) bool {
|
|
|
|
|
if len(s) != 64 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
for _, c := range s {
|
|
|
|
|
if (c < '0' || c > '9') && (c < 'a' || c > 'f') {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|