Two-Factor Authentication with Java and Google Authenticator

Ihor Sokolyk

26 Sep, 2019 · 4 min read

I am more than sure that each of you have at least one account with enabled Two-Factor Authentication (2FA). But if you are still unfamiliar with 2FA I’ll give you some general explanation.

It’s a second step in login sequence that asks you to enter 6-digits code sent to you by email, text message or Google Authenticator app and this code expires in 30 or 60 seconds. This second step of authentication makes your account more secure, because even if someone knows your login and password, they still need your physical mobile device to see 2FA code sent to you. Such approach is highly used in almost every single application, especially if this application has deal with money, cryptocurrencies, banks, transactions etc.

So in this article, as you may noticed, we will talk about using Google Authenticator app with your Java-based application. Let’s get started!

Maven Project

First of all, let’s create a maven project and add the following dependencies:




Here is why we need those dependencies in our project:

  • totp – The Time-based One-Time Password algorithm (TOTP) is an extension of the HMAC-based One-time Password algorithm (HOTP) generating a one-time password by instead taking uniqueness from the current time.
  • commons-codec– for converting inputs to hex and base32.
  • zxing – library for generating QR codes.

Also you need to install Google Authenticator app to your smartphone. It’s totally free and is available on App Store and Play Market. In order to add new entry to Google Authenticator app you need to enter manually a secret key or scan a QR code. I will show you how to use both of them in this tutorial. Let’s start with manual one first.

Google Authenticator requires 20 bytes secret key encoded as base32 string. We need to generate this key using the following code:

public static String generateSecretKey() {
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[20];
Base32 base32 = new Base32();
return base32.encodeToString(bytes);

After running this method you should see the generated string with 32 characters. Please write down this string somewhere since this is our secret key and we will use it later.


Now open your Google Authenticator app. Press ‘plus’ button to add a new entry and select ‘Manual entry’. In the ‘Account’ field enter your email address or any name and in ‘Key’ field paste our secret key. Press save button. You should see your entry in the list with 6-digits code that is changing every 30 seconds.

Now let’s write a method that converts base32 encoded secret keys to hex and uses the TOTP to turn them into 6-digits codes based on the current time.

public static String getTOTPCode(String secretKey) {
Base32 base32 = new Base32();
byte[] bytes = base32.decode(secretKey);
String hexKey = Hex.encodeHexString(bytes);
return TOTP.getOTP(hexKey);

Now let’s run the following code to generate time-based 6-digits code in sync with Google Authenticator.

String lastCode = null;
while (true) {
String code = getTOTPCode(secretKey);
if (!code.equals(lastCode)) {
lastCode = code;
try {
} catch (InterruptedException e) {};

If you did everything correctly then you should see the 6-digits code being displayed in console every 30 seconds and this code should be synchronized with code displayed in Google Authenticator. If they are not synchronized then make sure that time on your PC and mobile device is in synch.

QR code

We have finished with manual entry example, so let’s jump to QR code which is more user friendly and is used in most cases.

First of all we need to receive bar code data from google. It requires some special format, so here is our method to generate this data.

public static String getGoogleAuthenticatorBarCode(String secretKey, String account, String issuer) {
try {
return "otpauth://totp/"
+ URLEncoder.encode(issuer + ":" + account, "UTF-8").replace("+", "%20")
+ "?secret=" + URLEncoder.encode(secretKey, "UTF-8").replace("+", "%20")
+ "&issuer=" + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);

Here is some notes about the generated string above:

  • Account is the user id in system. Usually it’s user’s email or username. It’s used to label entries within Google Authenticator.
  • Issuer is a company or organization name and is also used for labelling purposes.
  • All dynamic values must be URL encoded.
  • Google Authenticator doesn’t seem to deal with spaces encoded as plus signs. Encoding spaces as %20 seems to work.

Now run the above code with some test account name, issuer name and secret key generated previously:

String email = "";
String companyName = "My Awesome Company";
String barCodeUrl = Utils.getGoogleAuthenticatorBarCode(secretKey, email, companyName);

You should receive a string in the following format:


Now the last step is left – to generate a QR code. Let’s use ZXing library to do it.

public static void createQRCode(String barCodeData, String filePath, int height, int width)
throws WriterException, IOException {
BitMatrix matrix = new MultiFormatWriter().encode(barCodeData, BarcodeFormat.QR_CODE,
width, height);
try (FileOutputStream out = new FileOutputStream(filePath)) {
MatrixToImageWriter.writeToStream(matrix, "png", out);

Calling this method with the string returned by the method in the previous step as the 1st argument will write a PNG image to the specified path with the specified height and width.

Go ahead and try to use your generated image with the “Scan barcode” option you saw previously in Google Authenticator. After scanning this QR code you should see a new entry in Google Authenticator entry list.

We can simulate user’ login into the system. Let’s imagine that user entered his credentials and now he need to enter 2FA code from Google Authenticator. Here is the easiest code snippet:

Scanner scanner = new Scanner(;
String code = scanner.nextLine();
if (code.equals(getTOTPCode(secretKey))) {
System.out.println("Logged in successfully");
} else {
System.out.println("Invalid 2FA Code");

Of course this is just a pseudo code, but it simulates the real 2FA flow and shows you if you did everything correctly.


Now you know the basics of two-factor authentication and you can try to integrate it into your web-based application with a small efforts to add more security to your application.

Hope you like this article. Do not forget to press ‘Clap’ button and share this article with your friends. The full example can be found on my GitHub account.

Have a great day! And don’t forget to enable 2FA in all your accounts:)

4.3/5.0 Article rating
3 Reviews
Was this article helpful? Please rate this article to give us valuable insights for our improvements.
  1. Wow!
  2. Mmm
  3. Hmm
  4. Meh
  5. hidden



Table of Contents

Secure your Spring Boot API with JSON Web Tokens

If you are reading this article I assume you are a bit familiar with Spring Boot and building API using it. Because the main purpose of this article is to show you a simple way how to make your API more secured.

Ihor Sokolyk

7 Jun, 2021 · 3 min read

Spring Cloud Gateway security with JWT

There is a clear understanding that everything that is exposed to the Internet should be secured. Especially when you create software and work with sensitive user data, such as emails, phone numbers, addresses, credit cards, etc. Here we will go through securing API Gateway with Json Web Tokens(JWT). As far as you probably know Spring […]

Ihor Kosandyak

26 Feb, 2021 · 4 min read

ORIL Front-end Digest (July 2020)

General How Emoji Can Improve Your Code—Seriously How to Become a Better Front-end Developer by Building Projects (Ideas Included) Keep Calm and Start Coding: How to Fight Coding Anxiety Javascript The Future Of JavaScript: Why It Is The Language Of The Next 10 Years How to Beat 5 Common JavaScript Interview Challenges Streamline Code Reviews […]

Volodymyr Padovskiy

17 Jul, 2020 · < 1 min read