bcrypt генерирует неправильные хэши - правильно ли обрабатывается мой пользовательский ввод? - PullRequest
0 голосов
/ 10 мая 2018

Я написал короткую программу на Go, чтобы сгенерировать хэш пароля bcrypt из пароля, предоставленного через stdin. Минимальный пример ниже:

package main

import (
    "bufio"
    "fmt"
    "golang.org/x/crypto/bcrypt"
)

func main() {

    fmt.Println("Enter password:")
    reader := bufio.NewReader(os.Stdin)
    inputPassword, _ := reader.ReadString('\n')

    inputPasswordBytes := []byte(inputPassword)
    hashBytes, _ := bcrypt.GenerateFromPassword(inputPasswordBytes, bcrypt.DefaultCost)

    hashStr := string(hashBytes)

    fmt.Println(hashStr)
}

В другой программе (веб-сервер Go) я принимаю пароль пользователя из запроса HTTP POST и проверяю его на хеш, сгенерированный с помощью приведенного выше кода и сохраненный в файле конфигурации, который загружается при запуске, например, так:

func authenticateHashedPassword(inputPassword string) bool {

    configPasswordHashBytes := []byte(server.Config.Net.Auth.Password)
    inputPasswordBytes := []byte(inputPassword)
    err := bcrypt.CompareHashAndPassword(configPasswordHashBytes, inputPasswordBytes)
    if err != nil {
        return false
    }
    return true

}

Однако это сообщает об ошибке, когда я знаю, inputPassword правильно. После некоторого исследования я увидел, что мои начальные значения func main выше генерировали неправильные выходные данные, когда я использовал этот веб-сайт для проверки своих значений: https://www.dailycred.com/article/bcrypt-calculator - он говорит, что все выходные данные, которые я генерирую, не соответствуют желаемым паролям.

Я предполагаю, что что-то не так происходит с кодировкой символов или другими деталями, когда я делаю []byte(inputPassword) - возможно, это включает в себя завершающий конец строки?

К сожалению, я не могу выполнить пошаговую отладку своей программы, поскольку языковые инструменты и отладчик кода Visual Studio Go не поддерживают использование стандартного ввода-вывода: https://github.com/Microsoft/vscode-go/issues/219

1 Ответ

0 голосов
/ 10 мая 2018

Метод bufio Reader.ReadString возвращает данные вплоть до разделителя \n включительно. \n включено в пароль. Используйте strings.TrimSpace , чтобы обрезать \n и любые пробелы, которые могли быть введены пользователем.

package main

import (
    "bufio"
    "fmt"
    "golang.org/x/crypto/bcrypt"
)

func main() {

    fmt.Println("Enter password:")
    reader := bufio.NewReader(os.Stdin)
    inputPassword, _ := strings.TrimSpace(reader.ReadString('\n'), "\n"))

    inputPasswordBytes := []byte(inputPassword)
    hashed, _ := bcrypt.GenerateFromPassword(inputPasswordBytes, bcrypt.DefaultCost)

    fmt.Printf("%s\n", hashed)
}
...