func createStrengthPrompt(password []rune) string {
	symbol, color := "", Red
	strength := zxcvbn.PasswordStrength(string(password), nil)

	switch {
	case strength.Score <= 1:
		symbol = "✗"
		color = Red
	case strength.Score <= 2:
		symbol = "⚡"
		color = Magenta
	case strength.Score <= 3:
		symbol = "⚠"
		color = Yellow
	case strength.Score <= 4:
		symbol = "✔"
		color = Green
	}

	prompt := Colorize(symbol, color)
	if strength.Entropy > 0 {
		entropy := fmt.Sprintf(" %3.0f", strength.Entropy)
		prompt += Colorize(entropy, Cyan)
	} else {
		prompt += Colorize(" ENT", Cyan)
	}

	prompt += Colorize(" New Password: ", color)
	return prompt
}
Example #2
0
func createStrengthPrompt(password []rune, prefix string) string {
	symbol, color := "", colors.Red
	strength := zxcvbn.PasswordStrength(string(password), nil)

	switch {
	case strength.Score <= 1:
		symbol = "✗"
		color = colors.Red
	case strength.Score <= 2:
		symbol = "⚡"
		color = colors.Magenta
	case strength.Score <= 3:
		symbol = "⚠"
		color = colors.Yellow
	case strength.Score <= 4:
		symbol = "✔"
		color = colors.Green
	}

	prompt := colors.Colorize(symbol, color)
	if strength.Entropy > 0 {
		entropy := fmt.Sprintf(" %3.0f", strength.Entropy)
		prompt += colors.Colorize(entropy, colors.Cyan)
	} else {
		prompt += colors.Colorize(" ENT", colors.Cyan)
	}

	prompt += colors.Colorize(" "+prefix+"passphrase: ", color)
	return prompt
}
Example #3
0
// PromptNewPassword asks the user to input a password.
//
// While typing, the user gets feedback by the prompt color,
// which changes with the security of the password to green.
// Additionally the entrtopy of the password is shown.
// If minEntropy was not reached after hitting enter,
// this function will log a message and ask the user again.
func PromptNewPassword(minEntropy float64) ([]byte, error) {
	rl, err := readline.New("")
	if err != nil {
		return nil, err
	}
	defer util.Closer(rl)

	passwordCfg := rl.GenPasswordConfig()
	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "   New "))
		rl.Refresh()
		return nil, 0, false
	})

	pwd := []byte{}

	for {
		pwd, err = rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		strength := zxcvbn.PasswordStrength(string(pwd), nil)
		if strength.Entropy >= minEntropy {
			break
		}

		fmt.Printf(colors.Colorize(msgLowEntropy, colors.Yellow)+"\n", minEntropy)
	}

	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "Retype "))
		rl.Refresh()
		return nil, 0, false
	})

	fmt.Println(colors.Colorize(msgReEnter, colors.Green))

	for {
		newPwd, err := rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		if bytes.Equal(pwd, newPwd) {
			break
		}

		fmt.Println(colors.Colorize(msgBadPassword, colors.Yellow))
	}

	return pwd, nil
}
Example #4
0
// DeterminePasswordStrength returns a detailed info about the strength of the given password
// @userInput e.g. user name. Given strings are matched against password to prohibit similarities between username and password
func DeterminePasswordStrength(password string, userInput []string) scoring.MinEntropyMatch {
	return zxcbvn.PasswordStrength(password, userInput)
}