You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 01:40:21