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