Я делюсь этим здесь, потому что первое, что я попробовал, не сработало, и, поскольку я публично спросил, я счел справедливым также публично поделиться решением. Это решение , конкретное c для моей ситуации. Я не утверждаю, что это решение или что нет лучших решений (пожалуйста, опубликуйте их!). Для моей конкретной ситуации c вот что я придумал ... [ EDIT : обратите внимание, что пользователь Mar c предложил посмотреть на эту библиотеку в комментарии выше, пока я писал это. Спасибо, мар c, моя фу явно лучше]
Как уже говорилось, моей первой попыткой было просто использовать библиотеку bcrypt, но это не сработало. При ближайшем рассмотрении я обнаружил, что bcrypt выводит только в одном формате (т.е. использует один алгоритм для хеширования), который явно НЕ совместим с системой паролей в Linux (по крайней мере, не в моем конкретном дистрибутиве). Таким образом, хотя результат в целом выглядел так, как должен, детали были следующими:
bcrypt дает мне что-то вроде: $2$10$sdfUILYhjd.HEdhjsdfgjhfdgjh.HEWjhndcjv
В этом первом поле ($2
) мой дистрибутив Linux не поддерживает тип $2
по-видимому (?) (Широко поддерживаются $1, $5, $6
(т.е. md5, sha256 и sha512)). Мне показалось, что у меня не было способа указать другой алгоритм в библиотеке bcrypt
go. Итак, я стал искать другие подходы / решения. Я пришел к следующему:
package main
import (
"fmt"
"math/rand"
"os"
"time"
"github.com/tredoe/osutil/user/crypt/sha512_crypt"
)
func encryptPassword(userPassword string) string {
// Generate a random string for use in the salt
const charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
s := make([]byte, 8)
for i := range s {
s[i] = charset[seededRand.Intn(len(charset))]
}
salt := []byte(fmt.Sprintf("$6$%s", s))
// use salt to hash user-supplied password
c := sha512_crypt.New()
hash, err := c.Generate([]byte(userPassword), salt)
if err != nil {
fmt.Printf("error hashing user's supplied password: %s\n", err)
os.Exit(1)
}
return string(hash)
}
Эта функция возвращает строки, которые выглядят так:
$6$tZeuYPZ3$3mj70WOprJj5ytFFzC8gUFYk7eymQvaR4lDg5C0WzwBAMupRAan7BaC6EAbL9Eiyi2GZR6PQIQQa.y6kZLqh6
, которые вы можете просто вставить прямо в /etc/shadow
или предоставить установщику в виде хешированного пароля (kickstart
, cloud-init
, et c) и go о вашей компании. В моем случае я пишу библиотечную функцию для приложения, которое я могу вызвать из утилиты командной строки или из службы api, которая, в свою очередь, предоставляет эту хешированную строку в качестве параметра для cloud-init.
HTH другие, которые могут найти это в будущем.