I want to create a user using a password that has already been hashed (using argon2). This is to validate the user migration process from my application's database to Keycloak.
I went to Authentication > Policies and configured the Hashing Algorithm as argon2. This way, when I create a "regular" password, it is automatically hashed to argon2.
I generated a hash using argon2 on the argon2.online platform. The parameters I used were the same as the default ones in Keycloak:
- Plain Text Input: password
- Salt: abcd1234
- Parallelism Factor: 1
- Memory Cost: 7168
- Iterations: 5
- Hash Length: 32
Using the Argon2id, the generated output was: $argon2id$v=19$m=7168,t=5,p=1$YWJjZDEyMzQ$M2pBlbaI2O0icDQslGeP1dTAVUxdnzx7GZr9N1Fdd04
I am using the following code to create a random user and then login:
import keycloak
import json
from datetime import datetime
password = 'password'
argon2_data = {
'plain_text_input': password,
'salt': 'abcd1234',
'parallelism': 1,
'memory_cost': 7168,
'iterations': 5,
'hash_length': 32,
'hash': '$argon2id$v=19$m=7168,t=5,p=1$YWJjZDEyMzQ$M2pBlbaI2O0icDQslGeP1dTAVUxdnzx7GZr9N1Fdd04',
'version': '1.3',
}
argon2_data['hash_parts'] = argon2_data['hash'].split('$')
def create_user():
ts = datetime.now().strftime("%H%M%S")
username = f"john{ts}"
basic_credentials = {
'type': 'password',
'temporary': False,
'value': password,
}
argon2_credentials = {
'type': 'password',
'temporary': False,
'secretData': json.dumps({
'value': argon2_data['hash_parts'][-1],
'salt': argon2_data['hash_parts'][-2],
}),
'credentialData': json.dumps({
'hashIterations': argon2_data['iterations'],
'algorithm': 'argon2',
'additionalParameters': {
'hashLength': [str(argon2_data['hash_length'])],
'memory': [str(argon2_data['memory_cost'])],
'type': ['id'],
'version': [argon2_data['version']],
'parallelism': [str(argon2_data['parallelism'])],
}
})
}
user_data = {
'attributes': {
'custom_key': 'custom_value'
},
'credentials': [
#basic_credentials,
argon2_credentials,
],
'username': username,
'firstName': 'John',
'lastName': 'Doe',
'email': f'{username}@doe.com.br',
'emailVerified': True,
'enabled': True
}
print(user_data)
keycloak.create_user(user_data)
return user_data
user = create_user()
keycloak.test_login(user['username'], password)
Creating the user using basic_credentials allows me to log in successfully immediately. However, creating the user using argon2_credentials causes the login to return the error "invalid user credentials".
What could I be doing wrong?

