use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.
the class HmacTest method testHmac.
@Test
public void testHmac() {
HmacOTP hmacOTP = new HmacOTP(6, HmacOTP.HMAC_SHA1, 10);
String secret = "JNSVMMTEKZCUGSKJIVGHMNSQOZBDA5JT";
String decoded = new String(Base32.decode(secret));
System.out.println(hmacOTP.generateHOTP(decoded, 0));
System.out.println(hmacOTP.validateHOTP("550233", decoded, 0));
Assert.assertEquals(1, hmacOTP.validateHOTP("550233", decoded, 0));
}
use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.
the class RequiredActionsTest method testOtp.
private void testOtp(String type, String algorithm, int digits, Integer period, Integer counter, String secret) {
switch(algorithm) {
case "SHA1":
algorithm = TimeBasedOTP.HMAC_SHA1;
break;
case "SHA256":
algorithm = TimeBasedOTP.HMAC_SHA256;
break;
case "SHA512":
algorithm = TimeBasedOTP.HMAC_SHA512;
break;
default:
throw new AssertionError("Wrong algorithm type");
}
HmacOTP otpGenerator;
String secretDecoded = new String(Base32.decode(secret));
String code;
switch(type) {
case TOTP:
otpGenerator = new TimeBasedOTP(algorithm, digits, period, 0);
code = ((TimeBasedOTP) otpGenerator).generateTOTP(secretDecoded);
break;
case HOTP:
otpGenerator = new HmacOTP(digits, algorithm, 0);
code = otpGenerator.generateHOTP(secretDecoded, counter);
break;
default:
throw new AssertionError("Wrong OTP type");
}
// fill in the form
otpSetupPage.setTotp(code);
otpSetupPage.submit();
assertLoginSuccessful();
// try the code is working
deleteAllSessionsInTestRealm();
testRealmAccountPage.navigateTo();
testRealmLoginPage.form().login(testUser);
oneTimeCodePage.assertCurrent();
// assertEquals("One-time code", oneTimeCodePage.getTotpLabel());
// bad attempt
oneTimeCodePage.submit();
assertTrue(oneTimeCodePage.feedbackMessage().isError());
assertEquals("[TEST LOCALE] vložen chybný kód", oneTimeCodePage.feedbackMessage().getText());
oneTimeCodePage.sendCode("XXXXXX");
assertTrue(oneTimeCodePage.feedbackMessage().isError());
assertEquals("[TEST LOCALE] vložen chybný kód", oneTimeCodePage.feedbackMessage().getText());
// generate new code
code = type.equals(TOTP) ? ((TimeBasedOTP) otpGenerator).generateTOTP(secretDecoded) : otpGenerator.generateHOTP(secretDecoded, ++counter);
oneTimeCodePage.sendCode(code);
assertLoginSuccessful();
}
use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.
the class LoginHotpTest method before.
@Before
public void before() throws MalformedURLException {
RealmRepresentation testRealm = testRealm().toRepresentation();
policy = new OTPPolicy();
policy.setAlgorithm(testRealm.getOtpPolicyAlgorithm());
policy.setDigits(testRealm.getOtpPolicyDigits());
policy.setInitialCounter(testRealm.getOtpPolicyInitialCounter());
policy.setLookAheadWindow(testRealm.getOtpPolicyLookAheadWindow());
policy.setPeriod(testRealm.getOtpPolicyLookAheadWindow());
policy.setType(testRealm.getOtpPolicyType());
otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
}
use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.
the class OTPCredentialProvider method isValid.
@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput credentialInput) {
if (!(credentialInput instanceof UserCredentialModel)) {
logger.debug("Expected instance of UserCredentialModel for CredentialInput");
return false;
}
String challengeResponse = credentialInput.getChallengeResponse();
if (challengeResponse == null) {
return false;
}
if (ObjectUtil.isBlank(credentialInput.getCredentialId())) {
logger.debugf("CredentialId is null when validating credential of user %s", user.getUsername());
return false;
}
CredentialModel credential = getCredentialStore().getStoredCredentialById(realm, user, credentialInput.getCredentialId());
OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromCredentialModel(credential);
OTPSecretData secretData = otpCredentialModel.getOTPSecretData();
OTPCredentialData credentialData = otpCredentialModel.getOTPCredentialData();
OTPPolicy policy = realm.getOTPPolicy();
if (OTPCredentialModel.HOTP.equals(credentialData.getSubType())) {
HmacOTP validator = new HmacOTP(credentialData.getDigits(), credentialData.getAlgorithm(), policy.getLookAheadWindow());
int counter = validator.validateHOTP(challengeResponse, secretData.getValue(), credentialData.getCounter());
if (counter < 0) {
return false;
}
otpCredentialModel.updateCounter(counter);
getCredentialStore().updateCredential(realm, user, otpCredentialModel);
return true;
} else if (OTPCredentialModel.TOTP.equals(credentialData.getSubType())) {
TimeBasedOTP validator = new TimeBasedOTP(credentialData.getAlgorithm(), credentialData.getDigits(), credentialData.getPeriod(), policy.getLookAheadWindow());
return validator.validateTOTP(challengeResponse, secretData.getValue().getBytes(StandardCharsets.UTF_8));
}
return false;
}
use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.
the class RequiredActionTotpSetupTest method setupOtpPolicyChangedHotp.
@Test
public void setupOtpPolicyChangedHotp() {
RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
RealmBuilder.edit(realmRep).otpLookAheadWindow(0).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.HOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
adminClient.realm("test").update(realmRep);
loginPage.open();
loginPage.login("test-user@localhost", "password");
totpPage.assertCurrent();
String totpSecret = totpPage.getTotpSecret();
HmacOTP otpgen = new HmacOTP(6, HmacOTP.HMAC_SHA1, 1);
totpPage.configure(otpgen.generateHOTP(totpSecret, 0));
String uri = driver.getCurrentUrl();
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).assertEvent().getDetails().get(Details.CODE_ID);
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin().session(sessionId).assertEvent();
oauth.openLogout();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
loginTotpPage.login(otpgen.generateHOTP(totpSecret, 1));
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
events.expectLogin().assertEvent();
oauth.openLogout();
events.expectLogout(null).session(AssertEvents.isUUID()).assertEvent();
// test lookAheadWindow
realmRep = adminClient.realm("test").toRepresentation();
RealmBuilder.edit(realmRep).otpLookAheadWindow(5).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.HOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
adminClient.realm("test").update(realmRep);
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
loginTotpPage.login(otpgen.generateHOTP(totpSecret, 2));
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
events.expectLogin().assertEvent();
// Revert
realmRep = adminClient.realm("test").toRepresentation();
RealmBuilder.edit(realmRep).otpLookAheadWindow(1).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.TOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
adminClient.realm("test").update(realmRep);
}
Aggregations