org.lib4j._2fa.GoogleAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for org.lib4j._2fa.GoogleAuthenticator.java

Source

/* Copyright (c) 2017 lib4j
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * You should have received a copy of The MIT License (MIT) along with this
 * program. If not, see <http://opensource.org/licenses/MIT/>.
 */

package org.lib4j._2fa;

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;
import org.ietf.tools.TOTP;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;

public final class GoogleAuthenticator {
    public static String getRandomSecretKey() {
        final byte[] bytes = new byte[20];
        new SecureRandom().nextBytes(bytes);
        return new Base32().encodeToString(bytes);
    }

    /**
     * @param secretKey Base32 encoded secret key (will be converted to
     *        upper-case, and may have optional whitespace which will be removed)
     * @param account The user's account name. e.g. an email address or a username
     * @param issuer The organization managing this account
     * @return The Google Authenticator barcode otpauth string
     *
     * @see <a href="https://github.com/google/google-authenticator/wiki/Key-Uri-Format">Key-Uri-Format</a>
     */
    public static String getGoogleAuthenticatorBarCode(final String secretKey, final String account,
            final String issuer) {
        final String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
        try {
            return "otpauth://totp/" + URLEncoder.encode(issuer + ":" + account, "UTF-8").replace("+", "%20")
                    + "?secret=" + URLEncoder.encode(normalizedBase32Key, "UTF-8").replace("+", "%20") + "&issuer="
                    + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20");
        } catch (final UnsupportedEncodingException e) {
            throw new UnsupportedOperationException(e);
        }
    }

    /**
     * @param secretKey Base32 encoded secret key (will be converted to
     *        upper-case, and may have optional whitespace which will be removed)
     * @return The TOTP code for the secret key.
     */
    public static String getTOTPCode(final String secretKey) {
        final String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();
        final byte[] bytes = new Base32().decode(normalizedBase32Key);
        final long time = (System.currentTimeMillis() / 1000) / 30;
        final String hexTime = Long.toHexString(time);
        return TOTP.generateTOTP(Hex.encodeHexString(bytes), hexTime, "6");
    }

    private GoogleAuthenticator() {
    }
}