Create QR code for Google Authenticator using ZXing in Java

How to create a QR code for Google Authenticator app (hereinafter referred to as app) in Java using ZXing (like zebra crossing). Even if I look it up on the net, Japanese information does not hit, so I will leave it in the article.

I referred to this area. https://remotestance.com/blog/2940/ https://github.com/google/google-authenticator/wiki/Key-Uri-Format http://weblabo.oscasierra.net/java-zxing-3/

First, put the code of the part that actually draws the QR code.

main.java


        String contents = "otpauth://totp/" + serviceName + ":" + userId+ 
                "?secret=" + secretKey + 
                "&issuer=" + issuer +
                "&algorithm=SHA1" +
                "&digits=6" +
                "&period=30";

        BarcodeFormat format = BarcodeFormat.QR_CODE;
        int width = 320;
        int height = 320;
        
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        
        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix bitMatrix = writer.encode(contents, format, width, height, hints);
        BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);

A description of the variables that suddenly appear in the code. serviceName: The name of the service userId: A name that identifies the user issuer: issuer name secretKey: key string

The top three are used to create the name of the key, and the fourth secretKey is the seed string. For example, if serviceName is Tokyo, Issuer is Japan, and userId is Chuo, the name of the key displayed in the app will be "Japan (Tokyo: Chuo)". Not only is it displayed, but if you scan the QR code with the same name in the app, the previously saved one will be overwritten without permission, so be careful not to use the same name in another service.

The behavior does not change whether algorithm, digits, or period are specified. Even if compatible apps appear in the future, the specifications will not change, so if you want to make the QR code cleaner, you should delete it.

Set the secreteKey to the base32 encoded key string. Using Google Authenticator naturally involves the process of creating an OTP (one-time password) on the server side, so you have to consider the consistency with that. When implemented in Java, this is probably the most used for OTP generation https://tools.ietf.org/html/rfc6238 Probably. Here is a code example of the OTP creation part assuming that the entire java code part included in RFC6238 is copied to TOTP.java to create the TOTP class.

main.java


        String seed = DatatypeConverter.printHexBinary(SecureRandom.getSeed(20));
        Date date = new Date();

        long T0 = 0;
        long X = 30;        
        long testTime = date.getTime()/1000;
        long T = (testTime - T0)/X;
        String steps = Long.toHexString(T).toUpperCase();
        while (steps.length() < 16) steps = "0" + steps;

        String otp = TOTP.generateTOTP(seed, steps, "6");

Since the app only supports SHA1, the seed length is 20 bytes (40 hexadecimal characters) and the function to call is for SHA1. Save this seed somewhere.

And the code to create the key string from seed is like this.

main.java


        byte byte_seed[] = DatatypeConverter.parseHexBinary(seed);
        String secretKey = new Base32().encodeToString(byte_seed);

Use the secretKey that came out as the secretKey of the QR code character string.

Recommended Posts

Create QR code for Google Authenticator using ZXing in Java
Create barcodes and QR codes in Java PDF
ChatWork4j for using the ChatWork API in Java
Technology for reading Java source code in Eclipse
Try using Sourcetrail (macOS version) in Java code
Create JSON in Java
I tried using Google Cloud Vision API in Java
I tried using an extended for statement in Java
Differences in code when using the length system in Java
Try using RocksDB in Java
Create hyperlinks in Java PowerPoint
Create Azure Functions in Java
Java in Visual Studio Code
Write Java8-like code in Java8
Tips for using Salesforce SOAP and Bulk API in Java
Talk about using Java input wait (Scanner) in VS Code
Avoid character code error in java when using VScode extension RUN-CODE
[Swift] Create UIButton class in code
Guess the character code in Java
Rock-paper-scissors game for beginners in Java
Java Spring environment in vs Code
[For beginners] Run Selenium in Java
Encrypt using RSA cryptography in Java
[Java] Boilerplate code elimination using Lombok
Create a Java project using Eclipse
[Java] Boilerplate code elimination using Lombok 2
HTTPS connection using tls1.2 in Java 6
I tried using JWT in Java
Settings for SSL debugging in Java
Sample code using Minio from Java
I tried using Elasticsearch API in Java
Sample code for Singleton implementation using enum
Create variable length binary data in Java
Memory measurement for Java apps using jstat
First steps for deep learning in Java
Key points for introducing gRPC in Java
Try using the Stream API in Java
Map without using an array in java
[Java] for Each and sorted in Lambda
Using JavaScript from Java in Rhino 2021 version
ERRORCODE = -4471 occurs in Java application using Db2.
Try using JSON format API in Java
Create Java Spring Boot project in IntelliJ
Enable code completion in Eclipse for Mac
Create a TODO app in Java 7 Create Header
Read Felica using RC-S380 (PaSoRi) in Java
All same hash code string in Java
Modern Java environment for Windows using Chocolatey
[Mac] Install Java in Visual Studio Code
Sample source code for finding the least common multiple of multiple values in Java
Impressions and doubts about using java for the first time in Android Studio
Create an animation in which characters emerge for a moment using molecular dynamics