82 lines
2.3 KiB
Markdown
82 lines
2.3 KiB
Markdown
# go-passwd
|
||
Its a multi password type checker. Using the [PHC string format](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md) we can identify a password hashing format from the prefix `$name$` and then dispatch the hashing or checking to its specific format.
|
||
|
||
|
||
# Example
|
||
|
||
Here is an example of usage:
|
||
|
||
```go
|
||
func Example() {
|
||
pass := "my_pass"
|
||
hash := "my_pass"
|
||
|
||
pwd := passwd.New(
|
||
&unix.MD5{}, // first is preferred type.
|
||
&plainPasswd{},
|
||
)
|
||
|
||
_, err := pwd.Passwd(pass, hash)
|
||
if err != nil {
|
||
fmt.Println("fail: ", err)
|
||
}
|
||
|
||
// Check if we want to update.
|
||
if !pwd.IsPreferred(hash) {
|
||
newHash, err := pwd.Passwd(pass, "")
|
||
if err != nil {
|
||
fmt.Println("fail: ", err)
|
||
}
|
||
|
||
fmt.Println("new hash:", newHash)
|
||
}
|
||
|
||
// Output:
|
||
// new hash: $1$81ed91e1131a3a5a50d8a68e8ef85fa0
|
||
}
|
||
```
|
||
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L33-L59
|
||
|
||
This shows how one would set a preferred hashing type and if the current version of ones password is not the preferred type updates it to enhance the security of the hashed password when someone logs in.
|
||
|
||
|
||
# Fallthrough
|
||
|
||
> Hold up now, that example hash doesn’t have a `$` prefix!
|
||
|
||
Well for this there is the option for a hash type to set itself as a fall through if a matching hash doesn’t exist. This is good for legacy password types that don’t follow the convention.
|
||
|
||
```go
|
||
func (p *plainPasswd) ApplyPasswd(passwd *passwd.Passwd) {
|
||
passwd.Register("plain", p)
|
||
passwd.SetFallthrough(p)
|
||
}
|
||
```
|
||
|
||
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L28-L31
|
||
|
||
|
||
# Custom Preference Checks
|
||
|
||
Circling back to the `IsPreferred` method. A hasher can define its own `IsPreferred` method that will be called to check if the current hash meets the complexity requirements. This is good for updating the password hashes to be more secure over time.
|
||
|
||
```go
|
||
func (p *Passwd) IsPreferred(hash string) bool {
|
||
_, algo := p.getAlgo(hash)
|
||
if algo != nil && algo == p.d {
|
||
|
||
// if the algorithm defines its own check for preference.
|
||
if ck, ok := algo.(interface{ IsPreferred(string) bool }); ok {
|
||
return ck.IsPreferred(hash)
|
||
}
|
||
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
```
|
||
|
||
https://github.com/sour-is/go-passwd/blob/main/passwd.go#L62-L74
|
||
|
||
Example: https://github.com/sour-is/go-passwd/blob/main/pkg/argon2/argon2.go#L104-L133
|