Skip to content

Problems with TOTP SHA512 #26

@Fale

Description

@Fale

Hi,
I use the following code (which is very similar to this example, if not for line 19 (which I added), line 38 (which I added), and the cycle (lines 56 and 64) which I added to simplify testing with multiple clients:

package main

import (
	"github.com/pquerna/otp"
	"github.com/pquerna/otp/totp"

	"bufio"
	"bytes"
	"fmt"
	"image/png"
	"io/ioutil"
	"os"
)

func display(key *otp.Key, data []byte) {
	fmt.Printf("Issuer:       %s\n", key.Issuer())
	fmt.Printf("Account Name: %s\n", key.AccountName())
	fmt.Printf("Secret:       %s\n", key.Secret())
	fmt.Printf("URL:          %s\n", key.URL())
	fmt.Println("Writing PNG to qr-code.png....")
	ioutil.WriteFile("qr-code.png", data, 0644)
	fmt.Println("")
	fmt.Println("Please add your TOTP to your OTP Application now!")
	fmt.Println("")
}

func promptForPasscode() string {
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("Enter Passcode: ")
	text, _ := reader.ReadString('\n')
	return text
}

func main() {
	key, err := totp.Generate(totp.GenerateOpts{
		Issuer:      "Example.com",
		AccountName: "alice@example.com",
		Algorithm:   otp.AlgorithmSHA512,
	})
	if err != nil {
		panic(err)
	}
	// Convert TOTP key into a PNG
	var buf bytes.Buffer
	img, err := key.Image(200, 200)
	if err != nil {
		panic(err)
	}
	png.Encode(&buf, img)

	// display the QR code to the user.
	display(key, buf.Bytes())

	// Now Validate that the user's successfully added the passcode.
	fmt.Println("Validating TOTP...")
	for {
		passcode := promptForPasscode()
		valid := totp.Validate(passcode, key.Secret())
		if valid {
			println("Valid passcode!")
		} else {
			println("Invalid passocde!")
		}
	}
}

In a test run, this is what it outputs:

Issuer:       Example.com
Account Name: alice@example.com
Secret:       N3K5NHE26HHXP2CL
URL:          otpauth://totp/Example.com:alice@example.com?algorithm=SHA512&digits=6&issuer=Example.com&period=30&secret=N3K5NHE26HHXP2CL

qr-code

I tried to add the QRCode to Google Authenticator (on Android), FreeOTP (on Android), Google Authenticator (on iOS), FreeOTP (on iOS), gopass (on Linux).

On multiple tests, FreeOTP (on both Android and iOS), Google Authenticator on iOS and gopass agree on the generated OTPs, while Google Authenticator on Android does not.
Only the code from Google Authenticator on Android is recognised as right.

Now, I'm not sure if this is a problem on the server side or on the client side, so I'm opening the ticket on both the clients (FreeOTP Android, gopass) and the server (github.com/pquerna/otp)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions