app.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "github.com/trustelem/zxcvbn"
  6. "math"
  7. "os"
  8. "passphrase-entropy/packages/haveibeenpwned"
  9. "strings"
  10. )
  11. func contains(arr [3]string, str string) bool {
  12. for _, a := range arr {
  13. if a == str {
  14. return true
  15. }
  16. }
  17. return false
  18. }
  19. func myUsage() {
  20. fmt.Println("usage: passphrase-strength <command> [<args>]")
  21. fmt.Println("Available commands are: ")
  22. fmt.Println(" diceware Calculate strength of a diceware passphrase")
  23. fmt.Println(" random Calculate strength of a random string")
  24. fmt.Println(" invented Calculate strength of an invented passphrase")
  25. }
  26. func secondsToHuman(guesses float64) (result string) {
  27. minute := float64(60)
  28. hour := minute * 60
  29. day := hour * 24
  30. month := day * 31
  31. year := month * 12
  32. century := year * 100
  33. if guesses < 1 {
  34. result = "< 1 second"
  35. } else if guesses < minute {
  36. result = fmt.Sprintf("%d seconds", int(math.Round(guesses)))
  37. } else if guesses < hour {
  38. result = fmt.Sprintf("%d minutes", int(math.Round(guesses / minute)))
  39. } else if guesses < day {
  40. result = fmt.Sprintf("%d hours", int(math.Round(guesses / hour)))
  41. } else if guesses < month {
  42. result = fmt.Sprintf("%d days", int(math.Round(guesses / day)))
  43. } else if guesses < year {
  44. result = fmt.Sprintf("%d months", int(math.Round(guesses / month)))
  45. } else if guesses < century {
  46. result = fmt.Sprintf("%d years", int(math.Round(guesses / year)))
  47. } else {
  48. result = fmt.Sprintf("Centuries")
  49. }
  50. return
  51. }
  52. func main() {
  53. var passphrase, words string
  54. var pwnedFlag, haveIBeenPwned bool
  55. var err error
  56. flag.StringVar(&passphrase,"password", "", "the password")
  57. flag.StringVar(&words, "words", "", "used words")
  58. flag.BoolVar(&pwnedFlag, "pwned", false, "check if password has been seen before")
  59. flag.Parse()
  60. if len(os.Args) == 1 || passphrase == "" {
  61. flag.PrintDefaults()
  62. return
  63. }
  64. if pwnedFlag == true {
  65. haveIBeenPwned, err = pwned.IsPasswordCompromised(passphrase)
  66. }
  67. if err != nil {
  68. fmt.Println("Something went wrong.")
  69. } else {
  70. userInput := strings.Fields(words)
  71. strength := zxcvbn.PasswordStrength(passphrase, userInput)
  72. guesses := strength.Guesses
  73. fmt.Printf("\nPassword:\t\t%s\n", passphrase)
  74. fmt.Printf("Password strength:\t%d/4\n", strength.Score)
  75. fmt.Printf("Guesses Log10:\t\t%f\n", math.Log10(float64(guesses)))
  76. fmt.Println("\nGuess times")
  77. fmt.Printf("100 / h:\t\t%s\t(throttled online attack)\n",secondsToHuman(guesses * (3600 / 100)))
  78. fmt.Printf("10 / s:\t\t%s\t(unthrottled online attack)\n",secondsToHuman(guesses/10))
  79. fmt.Printf("10k / s:\t\t%s\t(offline attack, slow hash, many cores)\n",secondsToHuman(guesses / 1e4))
  80. fmt.Printf("10b / s:\t\t%s\t(offline attack, slow hash, many cores)\n",secondsToHuman(guesses / 1e10))
  81. }
  82. if haveIBeenPwned == true {
  83. fmt.Println("\nThis password has been compromised and should not be used.")
  84. return
  85. }
  86. }