mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Session IDs and auth codes should have 128 bits of entropy
Closes #42274 Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
parent
b6cee86e74
commit
6ea3c8aedf
@ -2,6 +2,7 @@ package org.keycloak.common.util;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SecretGenerator {
|
||||
|
||||
@ -113,4 +114,13 @@ public class SecretGenerator {
|
||||
public static int equivalentEntropySize(int length, int srcAlphabetLength, int dstAlphabetLeng) {
|
||||
return (int) Math.ceil(length * ((Math.log(srcAlphabetLength)) / (Math.log(dstAlphabetLeng))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudo-UUID where all bits are random to have a maximum entropy.
|
||||
*
|
||||
* @return UUID with all bits random
|
||||
*/
|
||||
public UUID generateSecureUUID() {
|
||||
return new UUID(random.get().nextLong(), random.get().nextLong());
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,8 @@ import org.infinispan.affinity.KeyAffinityService;
|
||||
import org.infinispan.affinity.KeyAffinityServiceFactory;
|
||||
import org.infinispan.affinity.KeyGenerator;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.util.SecretGenerator;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.sessions.StickySessionEncoderProvider;
|
||||
|
||||
/**
|
||||
@ -88,7 +88,7 @@ public class InfinispanKeyGenerator {
|
||||
|
||||
@Override
|
||||
public UUID getKey() {
|
||||
return UUID.randomUUID();
|
||||
return SecretGenerator.getInstance().generateSecureUUID();
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ public class InfinispanKeyGenerator {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KeycloakModelUtils.generateId();
|
||||
return SecretGenerator.getInstance().generateSecureID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import org.keycloak.OAuthErrorException;
|
||||
import org.keycloak.TokenIdGenerator;
|
||||
import org.keycloak.authentication.AuthenticationProcessor;
|
||||
import org.keycloak.authentication.RequiredActionProvider;
|
||||
import org.keycloak.common.util.SecretGenerator;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.connections.httpclient.HttpClientProvider;
|
||||
import org.keycloak.constants.AdapterConstants;
|
||||
@ -65,7 +66,6 @@ import org.keycloak.util.TokenUtil;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.keycloak.protocol.oidc.grants.device.DeviceGrantType.approveOAuth2DeviceAuthorization;
|
||||
import static org.keycloak.protocol.oidc.grants.device.DeviceGrantType.denyOAuth2DeviceAuthorization;
|
||||
@ -251,7 +251,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
|
||||
// Standard or hybrid flow
|
||||
String code = null;
|
||||
if (responseType.hasResponseType(OIDCResponseType.CODE)) {
|
||||
OAuth2Code codeData = new OAuth2Code(UUID.randomUUID().toString(),
|
||||
OAuth2Code codeData = new OAuth2Code(SecretGenerator.getInstance().generateSecureID(),
|
||||
Time.currentTime() + userSession.getRealm().getAccessCodeLifespan(),
|
||||
nonce,
|
||||
authSession.getClientNote(OAuth2Constants.SCOPE),
|
||||
|
||||
@ -82,21 +82,13 @@ public class OAuth2CodeParser {
|
||||
return result.illegalCode();
|
||||
}
|
||||
|
||||
String codeUUID = parsed[0];
|
||||
String userSessionId = parsed[1];
|
||||
String clientUUID = parsed[2];
|
||||
|
||||
event.detail(Details.CODE_ID, userSessionId);
|
||||
event.session(userSessionId);
|
||||
|
||||
// Parse UUID
|
||||
String codeUUID;
|
||||
try {
|
||||
codeUUID = parsed[0];
|
||||
} catch (IllegalArgumentException re) {
|
||||
logger.warn("Invalid format of the UUID in the code");
|
||||
return result.illegalCode();
|
||||
}
|
||||
|
||||
// Retrieve UserSession
|
||||
var userSessionProvider = session.sessions();
|
||||
UserSessionModel userSession = userSessionProvider.getUserSessionIfClientExists(realm, userSessionId, false, clientUUID);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user