mirror of
https://github.com/wneessen/apg-go.git
synced 2024-11-10 00:02:54 +01:00
Added optional HIBP database check
Even though the generated passwords are generated in a secure way, there is a minimal chance, that the same password was used by someone before and this password was part of a leak. If you want to be on the safe side, you can now use the "-p" parameter, to have your newly generated password against the HIBP (https://haveibeenpwned.com) database. This feature is disabled by default, since it requires internet access and also the API call might take ~500ms to 1sec.
This commit is contained in:
parent
0badd56291
commit
5a29d4bc19
3 changed files with 58 additions and 0 deletions
13
apg.go
13
apg.go
|
@ -22,6 +22,7 @@ type Config struct {
|
||||||
useNumber bool
|
useNumber bool
|
||||||
useSpecial bool
|
useSpecial bool
|
||||||
humanReadable bool
|
humanReadable bool
|
||||||
|
checkHibp bool
|
||||||
excludeChars string
|
excludeChars string
|
||||||
newStyleModes string
|
newStyleModes string
|
||||||
spellPassword bool
|
spellPassword bool
|
||||||
|
@ -50,6 +51,8 @@ Options:
|
||||||
-H Avoid ambiguous characters in passwords (i. e.: 1, l, I, O, 0) (Default: off)
|
-H Avoid ambiguous characters in passwords (i. e.: 1, l, I, O, 0) (Default: off)
|
||||||
-C Enable complex password mode (implies -L -U -N -S and disables -H) (Default: off)
|
-C Enable complex password mode (implies -L -U -N -S and disables -H) (Default: off)
|
||||||
-l Spell generated passwords in phonetic alphabet (Default: off)
|
-l Spell generated passwords in phonetic alphabet (Default: off)
|
||||||
|
-p Check the HIBP database if the generated passwords was found in a leak before (Default: off)
|
||||||
|
'--> this feature requires internet connectivity
|
||||||
-h Show this help text
|
-h Show this help text
|
||||||
-v Show version string`
|
-v Show version string`
|
||||||
|
|
||||||
|
@ -96,5 +99,15 @@ func main() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.checkHibp {
|
||||||
|
isPwned, err := checkHibp(pwString)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("unable to check HIBP database: %v", err)
|
||||||
|
}
|
||||||
|
if isPwned {
|
||||||
|
fmt.Print("^-- !!WARNING: The previously generated password was found in HIPB database. Do not use it!!\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ func parseFlags() Config {
|
||||||
flag.BoolVar(&switchConf.useComplex, "C", false, "Generate complex passwords (implies -L -U -N -S, disables -H)")
|
flag.BoolVar(&switchConf.useComplex, "C", false, "Generate complex passwords (implies -L -U -N -S, disables -H)")
|
||||||
flag.BoolVar(&switchConf.humanReadable, "H", false, "Generate human-readable passwords")
|
flag.BoolVar(&switchConf.humanReadable, "H", false, "Generate human-readable passwords")
|
||||||
flag.BoolVar(&config.spellPassword, "l", false, "Spell generated password")
|
flag.BoolVar(&config.spellPassword, "l", false, "Spell generated password")
|
||||||
|
flag.BoolVar(&config.checkHibp, "p", false, "Check the HIBP database if the generated password was leaked before")
|
||||||
flag.BoolVar(&config.showVersion, "v", false, "Show version")
|
flag.BoolVar(&config.showVersion, "v", false, "Show version")
|
||||||
flag.IntVar(&config.minPassLen, "m", DefaultMinLenght, "Minimum password length")
|
flag.IntVar(&config.minPassLen, "m", DefaultMinLenght, "Minimum password length")
|
||||||
flag.IntVar(&config.maxPassLen, "x", DefaultMaxLenght, "Maxiumum password length")
|
flag.IntVar(&config.maxPassLen, "x", DefaultMaxLenght, "Maxiumum password length")
|
||||||
|
|
44
hibp.go
Normal file
44
hibp.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/sha1"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkHibp(p string) (bool, error) {
|
||||||
|
shaSum := fmt.Sprintf("%x", sha1.Sum([]byte(p)))
|
||||||
|
firstPart := shaSum[0:5]
|
||||||
|
secondPart := shaSum[5:]
|
||||||
|
isPwned := false
|
||||||
|
|
||||||
|
httpClient := &http.Client{Timeout: time.Second * 2}
|
||||||
|
httpRes, err := httpClient.Get("https://api.pwnedpasswords.com/range/" + firstPart)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err := httpRes.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error while closing HTTP response body: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
scanObj := bufio.NewScanner(httpRes.Body)
|
||||||
|
for scanObj.Scan() {
|
||||||
|
scanLine := strings.SplitN(scanObj.Text(), ":", 2)
|
||||||
|
if strings.ToLower(scanLine[0]) == secondPart {
|
||||||
|
isPwned = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := scanObj.Err(); err != nil {
|
||||||
|
return isPwned, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPwned, nil
|
||||||
|
}
|
Loading…
Reference in a new issue