Dev (Back & Front)ARTIGO

Capturando senhas no terminal com Go

Capturando senhas no terminal com Go
Imagem: Cesar Gimenes

Ler uma senha no terminal parece trivial, mas tem duas armadilhas: a senha aparece na tela se você usar a leitura comum, e você precisa garantir que é realmente um terminal e não redirecionamento. Vamos resolver as duas com o pacote golang.org/x/term.

Se você ler com bufio.Scanner ou fmt.Scanln, cada tecla aparece na tela. Para senha isso não serve. O term.ReadPassword lê direto do terminal, sem eco:

go
fd := int(os.Stdin.Fd()) // #nosec G115 -- stdin's fd is small; the conversion is safe
fmt.Print("password: ")
pass, err := term.ReadPassword(fd)
fmt.Println() // the user's Enter doesn't emit a newline; we do it

código fonte completo em

Se a entrada vier de um pipe, não há terminal para desligar o eco. Vale recusar antes:

go
if !term.IsTerminal(fd) {
    return "", errors.New("an interactive terminal is required for the password")
}

Quando a senha é nova, peça duas vezes e compare. Assim um erro de digitação não cria um segredo que você nunca mais consegue abrir:

Também usamos #nosec G115 para ignorar o alerta de segurança sobre o uso de os.Stdin.Fd(), que é seguro neste contexto.

Para comparar as senhas, você pode fazer cast para strings mas o melhor é usar bytes.Equal, que é mais eficiente.

Trabalha com tecnologia desde a década de 90. Já atuou na área de educação e participou de projetos de mobilidade de grande volume para laboratórios farmacêuticos. Criou games tanto para PC, como para iOS. Hoje está direcionando seus esforços em plataformas de Sistemas Embarcados, IoT, microservices e cloud computing. É um entusiasta de tecnologias como Golang e Docker.

Ver perfil