Two-factor passwords
Telegram's two-step verification (2FA) adds a cloud password on top of the login code. gotd never sends the password over the wire — it computes an SRP proof locally and sends only that.
With the auth flow
When you use auth.Flow, the password comes from your
UserAuthenticator.Password method. If the account has a password, gotd calls it
automatically after the code step:
func (a termAuth) Password(_ context.Context) (string, error) {
fmt.Print("Enter 2FA password: ")
pwd, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return "", err
}
return strings.TrimSpace(string(pwd)), nil
}
auth.Constant(phone, password, code) and auth.Env(prefix, code) supply the password
for you when you already have it.
Completing 2FA directly
After a flow that stopped at SESSION_PASSWORD_NEEDED (for example
QR login), finish with:
if _, err := client.Auth().Password(ctx, password); err != nil {
return err
}
Keeping the password out of plain memory
A plain Go string lingers in memory and may be swapped to disk. For hardened
applications, the secure-password
example keeps the password in a memguard
enclave and computes the SRP proof straight from it, never materializing a string. It
does so by overriding PasswordHash on the authenticator:
import "github.com/gotd/td/telegram/auth/srpguard"
type securePassword struct {
auth.UserAuthenticator
enclave *memguard.Enclave
}
func (s securePassword) PasswordHash(
ctx context.Context, p *tg.AccountPassword,
) (*tg.InputCheckPasswordSRP, error) {
return srpguard.Enclave(s.enclave)(ctx, p)
}
Use this approach when running on shared or untrusted hosts.