将Argon2哈希密码导入Keycloak后登录失败问题排查
Keycloak导入预哈希Argon2密码登录失败问题解决
问题背景
我需要将自有应用数据库中已用Argon2哈希的密码迁移到Keycloak,验证迁移流程。已在Keycloak的「Authentication > Policies」中配置Argon2为哈希算法,使用普通密码创建用户时可自动转为Argon2哈希并正常登录。
我生成了与Keycloak默认参数一致的Argon2id哈希:
- 明文密码:
password - 盐值:
abcd1234 - 并行因子:1
- 内存成本:7168
- 迭代次数:5
- 哈希长度:32
最终哈希结果:$argon2id$v=19$m=7168,t=5,p=1$YWJjZDEyMzQ$M2pBlbaI2O0icDQslGeP1dTAVUxdnzx7GZr9N1Fdd04
使用Python代码创建用户时,用明文密码的basic_credentials可正常登录,但使用预哈希的argon2_credentials创建后,登录返回「invalid user credentials」错误,代码如下:
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)
错误原因及修正
1. additionalParameters参数格式错误
Keycloak解析Argon2参数时,要求参数值为原始类型(数字/字符串),而非数组。你当前所有参数值都用数组包裹(如'hashLength': [str(32)]),导致Keycloak无法正确读取参数,验证时计算的哈希与存储值不匹配。
2. 版本参数不匹配
哈希串中的v=19对应Argon2 1.3版本,但你传入的是字符串'1.3',Keycloak需要的是数值类型的版本号19。
修正后的argon2_credentials代码
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': argon2_data['hash_length'], 'memory': argon2_data['memory_cost'], 'type': 'id', 'version': 19, # 对应哈希串中的v=19 'parallelism': argon2_data['parallelism'], } }) }
验证建议
修正后重新创建用户,尝试登录即可正常验证。也可通过Keycloak后台确认参数:进入用户详情页 → 「Credentials」标签 → 点击密码凭证的「View details」,检查显示的参数是否与配置一致。
内容的提问来源于stack exchange,提问作者Victor Nolêto
相关产品推荐
相关产品推荐

