Skip to content

Instantly share code, notes, and snippets.

@meehanman
Last active March 27, 2024 11:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meehanman/0e6e53b8d293733ac9074a6dc1e236ea to your computer and use it in GitHub Desktop.
Save meehanman/0e6e53b8d293733ac9074a6dc1e236ea to your computer and use it in GitHub Desktop.
TOTP-Go

TOTP-Go

TOTP in your terminal (with built in add to clipboard) written to go. This is a quick hack and the secret keys are hard-coded into the binary for this example.

Get your TOTP Codes from Authy via alexzorin/authy: authy-export

AUTHY_EXPORT_PASSWORD='<MY_EXPORT_PASSWORD>' go run cmd/authy-export/authy-export.go
otpauth://totp/....?secret=redacted
otpauth://totp/....?secret=redacted
otpauth://totp/....?secret=redacted

Usage: Generating all Tokens

> go run totp.go 
or
❯ ./totp-go
226139 gitlab
445113 google
717220 personal

Usage: Copying 1 Token to the Clipboard

Web Browser for easy pasting:

❯ ./totp-go per
127635 personal Copied to Clipboard

Usage: Only Displaying the totp and not copying to clipboard

Can be used in bash substitution:

❯ ./totp-go per !
127635

Building

# Sync packages
go mod tidy
# Run Code
go run totp.go
# Build Binary
go build
# Run Binary
./totp-go sec
# Copy to local bin
cp totp-go /usr/local/bin
package main
import (
"fmt"
"github.com/atotto/clipboard"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
"os"
"strings"
"time"
)
var otpList = map[string]string{
"gitlab": "otpauth://totp/gitlab:email@address.com?digits=6&secret=AAABBBBCCCCDDDDD",
"google": "otpauth://totp/google:email@address.com?digits=6&secret=XXXXYYYYYZZZZZZ",
"personal": "otpauth://totp/personal:username?digits=6&secret=AAABBBBCCCCDDDDDEEEEFFFF",
}
func main() {
grep := ""
quiet := false
if len(os.Args) > 1 {
grep = os.Args[1]
}
if len(os.Args) > 2 {
quiet = true
}
for secret, uri := range otpList {
key, err := otp.NewKeyFromURL(uri)
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing URI: %v\n", err)
continue
}
if grep == "" {
totpCode, err := totp.GenerateCode(key.Secret(), time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating TOTP code: %v\n", err)
continue
}
fmt.Printf("%s %s\n", totpCode, secret)
continue
}
if strings.Contains(secret, grep) {
totpCode, err := totp.GenerateCode(key.Secret(), time.Now())
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating TOTP code: %v\n", err)
continue
}
if !quiet {
fmt.Printf("%s %s %s\n", totpCode, secret, "Copied to Clipboard")
err = clipboard.WriteAll(totpCode)
} else {
fmt.Printf("%s\n", totpCode)
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error copying to clipboard: %v\n", err)
}
break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment