package io.cos.cas.authentication.oath; import org.apache.commons.codec.binary.Base32; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; /** * Copied from @{link https://github.com/parkghost/TOTP-authentication-demo}. * * <strong>NOTE: </strong> in order to use this class in CAS maven war overlays, exclude the following jar in the * maven-war-plugin->configuration->overlays->excludes section of local maven overlay pom.xml: WEB-INF/lib/commons-codec-1.4.jar * * @author Dmitriy Kopylenko * @author Unicon, inc. * @author Michael Haselton * @since 0.5 */ public final class TotpUtils { private static final int PASS_CODE_LENGTH = 6; private static final String CRYPTO = "HmacSHA1"; /** * A private constructor for the utility class. */ private TotpUtils() { } /** * Checks a Time-based One Time Password Code. * * @param secret the totp secret * @param code the code to verify * @param interval the totp interval * @param window the totp window * @return a boolean value indicating if the check passes or fails * * @throws NoSuchAlgorithmException On no such algorithm found to perform the check. * @throws InvalidKeyException On the case when the key is invalid. */ public static boolean checkCode(final String secret, final long code, final int interval, final int window) throws NoSuchAlgorithmException, InvalidKeyException { final Base32 codec = new Base32(); final byte[] decodedKey = codec.decode(secret); final long currentTimeSeconds = System.currentTimeMillis() / 1000; final long currentInterval = currentTimeSeconds / interval; for (int i = -window; i <= window; ++i) { final long hash = Totp.generateTotp(decodedKey, currentInterval + i, PASS_CODE_LENGTH, CRYPTO); if (hash == code) { return true; } } // The validation code is invalid. return false; } }