Migrate SHA256 hashed passwords to Keycloak

Hi,

I’m currently evaluating migrating our authentication stuff to keycloak.

I already have a bunch of users saved in a database, including their username, salt and hashed password hashed by SHA256.

Now I’m trying to migrate those users into my keycloak instance, because I don’t want them to need to reset their passwords if I do the migration.

I’ve tried this answer to get started with the Java admin client, however I always get a 400 Bad Request as a response, which I think is because the value field is empty (although stated as optional in the documentation)

This is what I’ve come up with:

var newCredentials = new CredentialRepresentation();
newCredentials.setTemporary(false);
newCredentials.setType(CredentialRepresentation.PASSWORD);
newCredentials.setSecretData(createSecretJson(salt, hash));
newCredentials.setCredentialData(credateCredentialJson());

var userId = realm.users().search(username, true).get(0).getId();
var user = realm.users().get(userId);
user.resetPassword(newCredentials);

and this is the response:

javax.ws.rs.BadRequestException: HTTP 400 Bad Request
	at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:219)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.DefaultEntityExtractorFactory$3.extractEntity(DefaultEntityExtractorFactory.java:50)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:151)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:112)
	at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)
	at com.sun.proxy.$Proxy37.resetPassword(Unknown Source)

I also can’t find any indication about the error in the log (using level DEBUG).

Updating the user representation like this:

var newCredentials = new CredentialRepresentation();
newCredentials.setTemporary(false);
newCredentials.setType(CredentialRepresentation.PASSWORD);
newCredentials.setSecretData(createSecretJson(salt, hash));
newCredentials.setCredentialData(credateCredentialJson());

var userId = realm.users().search(username, true).get(0).getId();
var user = realm.users().get(userId);
var userRepresentation = user.toRepresentation();

userRepresentation.setCredentials(List.of(newCredentials));
user.update(userRepresentation);

Does save the credentials, but I’m not able to login (wrong password).

The salt and hash is encoded as Base64 before being sent to the API.

The JSON that gets send for the credential representation is:
{"type":"password","secretData":"{"value":"MWQ3MDc4MTE5ODgwNjljYTc2MDgyNjg2MWQ2ZDYzYTEwZThjM2I3ZjE3MWM0NDQxYTY0NzJlYTU4YzExNzExYg==","salt":"YXNkZmFzZGY="}","credentialData":"{"hashIterations":1,"algorithm":"HS256"}","temporary":false}

1 Like

Hello, I am trying to migrate hashed passwords too in the same way, with no success… Did you achieve it? Could you please help me?

Hi, @MarAm and @littlesafra did you succeed with your objective? Could you share with us your results?

Hello @littlesafra @dvlpphb - did any of you get it to work?

Did you get works, pls share with us facing the same issue.