package me.brandonc.security.totp.util;
import static org.junit.Assert.assertEquals;
import java.security.GeneralSecurityException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
public class TOTPTest {
private static final String CRYPTO = "HmacSHA1";
@Test
public void generateTOTPTest() throws DecoderException {
String keyString = "3132333435363738393031323334353637383930";
byte[] key = Hex.decodeHex(keyString.toCharArray());
assertEquals(generateGoogleOTP(key), generateRfcOTP(key));
}
private int generateRfcOTP(byte[] key) {
return TOTP.generateTOTP(key, getCurrentInterval(), 6, CRYPTO);
}
private int generateGoogleOTP(byte[] key) {
try {
Mac hmac;
hmac = Mac.getInstance(CRYPTO);
SecretKeySpec macKey = new SecretKeySpec(key, "RAW");
hmac.init(macKey);
PasscodeGenerator passcodeGenerator = new PasscodeGenerator(hmac);
return Integer.parseInt(passcodeGenerator.generateTimeoutCode());
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return 0;
}
private long getCurrentInterval() {
long currentTimeSeconds = System.currentTimeMillis() / 1000;
return currentTimeSeconds / 30;
}
}