diff --git a/pom.xml b/pom.xml index 951af58..c7aa00f 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.cringe_studios CringeAuthenticatorLibrary - 1.0 + 1.1 CringeAuthenticatorLibrary The Library of the Cringe Authenticator diff --git a/src/main/java/com/cringe_studios/cringe_authenticator_library/impl/HOTP.java b/src/main/java/com/cringe_studios/cringe_authenticator_library/impl/HOTP.java index eb61468..340591a 100644 --- a/src/main/java/com/cringe_studios/cringe_authenticator_library/impl/HOTP.java +++ b/src/main/java/com/cringe_studios/cringe_authenticator_library/impl/HOTP.java @@ -1,7 +1,11 @@ package com.cringe_studios.cringe_authenticator_library.impl; +import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import com.cringe_studios.cringe_authenticator_library.OTP; import com.cringe_studios.cringe_authenticator_library.OTPAlgorithm; @@ -66,11 +70,23 @@ public class HOTP extends OTP { int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); - int otp = binary % DIGITS_POWER[codeDigits]; + //int otp = binary % DIGITS_POWER[codeDigits]; + + //byte[] truncatedHash = Arrays.copyOfRange(hash, offset, offset + 3); + //truncatedHash[0] &= 0x7F; + //BigInteger bigBinary = new BigInteger(1, truncatedHash); + BigInteger bigBinary = BigInteger.valueOf(binary); + BigInteger bigOtp = bigBinary.mod(BigInteger.TEN.pow(codeDigits)); + + //System.out.println(binary + " vs. " + bigBinary.toString()); + //System.out.println(otp + " vs. " + bigOtp.toString()); + if (addChecksum) { - otp = (otp * 10) + HOTPChecksumProvider.calcChecksum(otp, codeDigits); + //otp = (otp * 10) + HOTPChecksumProvider.calcChecksum(otp, codeDigits); + bigOtp = bigOtp.multiply(BigInteger.TEN).add(BigInteger.valueOf(HOTPChecksumProvider.calcChecksum(bigOtp.longValue(), codeDigits))); } - String result = Integer.toString(otp); + //String result = Integer.toString(otp); + String result = bigOtp.toString(); while (result.length() < digits) { result = "0" + result; } diff --git a/src/test/java/test/OTPTest.java b/src/test/java/test/OTPTest.java index 28571b1..46e8b63 100644 --- a/src/test/java/test/OTPTest.java +++ b/src/test/java/test/OTPTest.java @@ -1,6 +1,8 @@ package test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.math.BigInteger; import java.text.DateFormat; @@ -44,6 +46,25 @@ public class OTPTest { assertEquals(calculatedPin, expectedValues[i]); } } + + @Test + public void lengthTest() { + String secret = "1"; + String base32secret = Base32.encode(hexStr2Bytes(secret)); + OTP testOTP1 = OTP.createNewOTP(OTPType.HOTP, base32secret, OTPAlgorithm.SHA1, 1, 0, 0, false); + assertDoesNotThrow(() -> testOTP1.getPin()); + + secret = "100"; + base32secret = Base32.encode(hexStr2Bytes(secret)); + OTP testOTP2 = OTP.createNewOTP(OTPType.HOTP, base32secret, OTPAlgorithm.SHA256, 0, 0, 0, false); + assertDoesNotThrow(() -> testOTP2.getPin()); + + OTP testOTP3 = OTP.createNewOTP(OTPType.HOTP, base32secret, OTPAlgorithm.SHA512, 50, 0, 0, false); + assertDoesNotThrow(() -> testOTP3.getPin()); + + OTP testOTP4 = OTP.createNewOTP(OTPType.HOTP, base32secret, OTPAlgorithm.SHA512, 10, 0, 0, false); + assertDoesNotThrow(() -> testOTP4.getPin()); + } private static byte[] hexStr2Bytes(String hex) { // Adding one byte to get the right conversion