Skip to content

Instantly share code, notes, and snippets.

@Arzumify
Last active April 19, 2024 18:34
Show Gist options
  • Save Arzumify/46c71840b97fbb0de59a2862d69039ed to your computer and use it in GitHub Desktop.
Save Arzumify/46c71840b97fbb0de59a2862d69039ed to your computer and use it in GitHub Desktop.
Werkzeug security hashes in go
// This isn't a full blown module, just copy the imports and copy the functions to use. Code is self explanatory.
import (
"encoding/hex"
"fmt"
"strings"
"math/rand"
"golang.org/x/crypto/scrypt"
)
const SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
func genSalt(length int) string {
if length <= 0 {
panic("Salt length must be at least 1.")
}
salt := make([]byte, length)
for i := range salt {
salt[i] = SALT_CHARS[rand.Intn(len(SALT_CHARS))]
}
return string(salt)
}
func hash(password, salt string) string {
passwordBytes := []byte(password)
saltBytes := []byte(salt)
if salt == "" {
salt = genSalt(16) // You can adjust the length of the salt as needed
}
derivedKey, _ := scrypt.Key(passwordBytes, saltBytes, 32768, 8, 1, 64)
hashString := fmt.Sprintf("scrypt:32768:8:1$%s$%s", salt, hex.EncodeToString(derivedKey))
return hashString
}
func verifyHash(werkzeughash, password string) (bool) {
parts := strings.Split(werkzeughash, "$")
if len(parts) != 3 || parts[0] != "scrypt:32768:8:1" {
return false, fmt.Errorf("invalid hash format", len(parts), parts[0], werkzeughash)
}
salt := parts[1]
computedHash := hash(password, salt)
fmt.Println(werkzeughash, "\n", computedHash)
return werkzeughash == computedHash, nil
}
@Arzumify
Copy link
Author

No license, feel free to just copy-paste, relicense, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment