Golang : Generate QR codes for Google Authenticator App and fix "Cannot interpret QR code" error
This is a supplement tutorial for the previous tutorial on how to generate QR codes with Golang and how to fix the error "Cannot interpret QR code"
To generate QR codes that is acceptable to Google Authenticator App. You need to follow the URI format specified in https://github.com/google/google-authenticator/wiki/Key-Uri-Format. Otherwise, the QR codes will not be interpreted correctly by Google Authenticator. Your app users will see the following error when attempt to scan the QR code.
Below is a code example on how to generate the proper QR codes for Google Authenticator :
package main
import (
"bytes"
"code.google.com/p/rsc/qr"
"crypto/rand"
"encoding/base32"
"fmt"
"github.com/disintegration/imaging"
"image"
"os"
"runtime"
)
func randStr(strSize int, randType string) string {
var dictionary string
if randType == "alphanum" {
dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
}
if randType == "alpha" {
dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
}
if randType == "number" {
dictionary = "0123456789"
}
var bytes = make([]byte, strSize)
rand.Read(bytes)
for k, v := range bytes {
bytes[k] = dictionary[v%byte(len(dictionary))]
}
return string(bytes)
}
func main() {
// maximize CPU usage for maximum performance
runtime.GOMAXPROCS(runtime.NumCPU())
// generate a random string - preferably 6 or 8 characters
randomStr := randStr(6, "alphanum")
fmt.Println(randomStr)
// For Google Authenticator purpose
// for more details see
// https://github.com/google/google-authenticator/wiki/Key-Uri-Format
secret := base32.StdEncoding.EncodeToString([]byte(randomStr))
// authentication link. Remember to replace SocketLoop with yours.
// for more details see
// https://github.com/google/google-authenticator/wiki/Key-Uri-Format
authLink := "otpauth://totp/SocketLoop?secret=" + secret + "&issuer=SocketLoop"
// Encode authLink to QR codes
// qr.H = 65% redundant level
// see https://godoc.org/code.google.com/p/rsc/qr#Level
code, err := qr.Encode(authLink, qr.H)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
imgByte := code.PNG()
// convert byte to image for saving to file
img, _, _ := image.Decode(bytes.NewReader(imgByte))
err = imaging.Save(img, "./QRImgGA.png")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// everything ok
fmt.Println("QR code generated and saved to QRimgGA.png")
}
Output ( tested with Google Authenticator app ) :
Hope this tutorial can be helpful to you!
References :
http://blog.gopheracademy.com/advent-2013/day-21-two-factor-auth/
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
See also : Golang : How to generate QR codes?
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+11.8k Golang : Convert(cast) int to int64
+10k How to tell if a binary(executable) file or web application is built with Golang?
+22.9k Golang : Convert long hexadecimal with strconv.ParseUint example
+12.1k Golang : How to check if a file is hidden?
+6.5k Golang : Get today's weekday name and calculate target day distance example
+11k Golang : Get terminal width and height example
+7.5k Golang : HTTP Routing with Goji example
+24.7k Golang : Encrypt and decrypt data with AES crypto
+8.3k Golang : Load ASN1 encoded DSA public key PEM file example
+22.1k Golang : How to print rune, unicode, utf-8 and non-ASCII CJK(Chinese/Japanese/Korean) characters?
+8.6k Golang : Random Rune generator
+39.5k Golang : Get hardware information such as disk, memory and CPU usage