Java tutorial
/* Copyright 2017 Petr Michalk Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cz.alej.michalik.totp.util; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.codec.binary.Base32; /** * Tda pro generovn TOTP hesla pomoc HOTP algoritmu podle RFC6238 * specifikace. Implemetuje Fluent interface. * * @author Petr Michalk * @see HOTP * @see <a href="https://tools.ietf.org/html/rfc6238">RFC6238</a> * */ public class TOTP implements OTP { // Bn se hesla generuj kadch 30 sekund private int step = 30; // asov posun private long t0 = 0; // Tda pro generovn hesla private HOTP hotp = new HOTP(); /** * Vytvo przdnou TOTP tdu */ public TOTP() { } /** * Vytvo novou TOTP tdu * * @param secret * string kl?e */ public TOTP(byte[] secret) { hotp.setSecret(secret); } /** * Nastav algoritmus vpo?tu HMAC hashe * * @param alg * algoritmus * @return sebe */ public TOTP setAlgorithm(String alg) { hotp.setAlgorithm(alg); return this; } /** * Nastav ?asov posun * * @param time * ?as v sekundch * @return sebe */ public TOTP setCounter(long time) { t0 = time; return this; } /** * Nastav po?et ?slic hesla v rozmez od 6 do 8 ?slic * * @param digits * po?et ?slic * @return sebe * @throws Error * patn po?et ?slic */ public TOTP setDigits(int digits) { hotp.setDigits(digits); return this; } /** * Nastav sdlen heslo * * @param secret * heslo jako byte[] * @return sebe */ public TOTP setSecret(byte[] secret) { hotp.setSecret(secret); return this; } /** * Nastav ?asov posun * * @param shift * ?as v sekundch * @return sebe */ public TOTP setShift(int shift) { this.t0 = shift; return this; } /** * Nastav jak ?asto se budou hesla generovat * * @param step * po?et vtein * @return sebe */ public TOTP setStep(int step) { this.step = step; return this; } /** * Vrt nastaven algoritmus * * @return algoritmus */ public String getAlgorithm() { return hotp.getAlgorithm(); } /** * Vrt nastaven po?tadlo (?as) * * @return po?tadlo */ public long getCounter() { return hotp.getCounter(); } /** * Vrt nastaven po?et ?slic * * @return po?et ?slic */ public int getDigits() { return hotp.getDigits(); } /** * Vrt nastaven ?asov posun * * @return ?as v sekundch */ public long getShift() { return t0; } /** * Vrt nastavenou periodu generovn hesla * * @return ?as v sekundch */ public int getStep() { return step; } /** * Vrt TOTP heslo pro aktuln ?as * * @return TOTP heslo jako int */ public int get() { long now = System.currentTimeMillis() / 1000; hotp.setCounter((int) Math.floor((now - t0) / step)); return hotp.get(); } /** * Vrt TOTP heslo pro aktuln ?as * * @return etzec hesla */ public String toString() { int pass = get(); // slo dopln zleva nulami return String.format("%0" + hotp.getDigits() + "d", pass); } /** * Ukzka TOTP pro zprvu "12345678901234567890" */ public static void main(String[] args) { // GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ v base32 String secret = "12345678901234567890"; System.out.printf("Heslo je: %s \nV Base32 to je: %s\n", secret, new Base32().encodeToString(secret.getBytes())); TOTP t = new TOTP(secret.getBytes()); System.out.printf("%s\n", t); while (true) { int time = Integer.valueOf(new SimpleDateFormat("ss").format(new Date())); if (time % 30 == 0) { System.out.printf("%s\n", t); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }