emqx mysql pbkdf2认证问题


这是我的配置
这是查出来的hash值和盐
A4D81439B35BF8F95FEDD6D95005C26C71ACFB7F223BAACF811F54AC54DF4270
3be7fa3a552bbdb7055a8f6d08d6a966
为什么鉴权还是不过呢?
另外社区的方法用了端口被占用
emqx@emqx-core-d894447cf-0:/opt/emqx$ ./bin/emqx console
EMQX_API_KEY__BOOTSTRAP_FILE [api_key.bootstrap_file]: /opt/emqx/data/bootstrap_api_key
EMQX_DASHBOARD__LISTENERS__HTTP__BIND [dashboard.listeners.http.bind]: 18083
EMQX_CLUSTER__DNS__RECORD_TYPE [cluster.dns.record_type]: srv
EMQX_CLUSTER__DNS__NAME [cluster.dns.name]: emqx-headless.emqx.svc.cluster.local
EMQX_CLUSTER__DISCOVERY_STRATEGY [cluster.discovery_strategy]: dns
EMQX_NODE__ROLE [node.role]: core
EMQX_NODE__DATA_DIR [node.data_dir]: data
EMQX_NODE__COOKIE [node.cookie]: ******
Protocol ‘ekka’: register/listen error: “port 4370 is in use”
emqx@emqx-core-d894447cf-0:/opt/emqx$

你应该说的是认证不过吧,大概率是你的算法的参数没对上?

你看以看看这个端口是谁在用,我猜应该是上一个 emqx 没停,又启动一个?

我仔细看过了我的算法是没问题的。
我直接用生成的hash来手动改的数据库,都不涉及到我自己代码生成的部分。还没有认证通过。
./bin/emqx eval ‘Salt = binary:decode_hex(<<“3be7fa3a552bbdb7055a8f6d08d6a966”>>), HashBin = crypto:pbkdf2_hmac(sha256, <<“123456”>>, Salt, 10000, 32), io:format(“~s~n”, [binary:encode_hex(HashBin)]).’
A4D81439B35BF8F95FEDD6D95005C26C71ACFB7F223BAACF811F54AC54DF4270
ok

我库里很简单就填了
3be7fa3a552bbdb7055a8f6d08d6a966

A4D81439B35BF8F95FEDD6D95005C26C71ACFB7F223BAACF811F54AC54DF4270
但是还是没有通过认证。
10000, 32 分别是循环次数和dk长度。
跟我截图里的在emqx里的是一致的

{“time”:1744801652963474,“level”:“debug”,“msg”:“mqtt_packet_received”,“clientid”:“12345”,“username”:“123”,“peername”:“172.27.175.51:59473”,“tag”:“MQTT”,“pid”:“<0.10322.0>”,“packet”:“CONNECT(Q0, R0, D0, ClientId=12345, ProtoName=MQTT, ProtoVsn=4, CleanStart=true, KeepAlive=60, Username=123, Password=******)”,“line”:572}

{“time”:1744801652963645,“level”:“debug”,“msg”:“mysql_connector_received”,“rule_trigger_ts”:,“client_ids”:{},“rule_ids”:{},“clientid”:“12345”,“sql”:“emqx_authn_mysql”,“username”:“123”,“connector”:“emqx_authn_mysql:2”,“peername”:“172.27.175.51:59473”,“state”:{“query_templates”:“#{{emqx_authn_mysql,prepstmt} => {[<<"SELECT \n password AS password_hash,\n password AS password,\n salt AS salt\nFROM xm_iot_cn.users\nLIMIT 1">>],}}”,“prepares”:“ok”,“pool_name”:“emqx_authn_mysql:2”},“tag”:“QUERY”,“pid”:“<0.10322.0>”,“line”:527}

{“time”:1744801652970861,“level”:“debug”,“msg”:“authenticator_result”,“authenticator”:“password_based:mysql”,“clientid”:“12345”,“username”:“123”,“result”:“{error,bad_username_or_password}”,“peername”:“172.27.175.51:59473”,“tag”:“AUTHN”,“pid”:“<0.10322.0>”,“line”:738}

{“time”:1744801652970959,“level”:“debug”,“msg”:“authentication_result”,“clientid”:“12345”,“username”:“123”,“result”:“{stop,{error,bad_username_or_password}}”,“peername”:“172.27.175.51:59473”,“tag”:“AUTHN”,“reason”:“chain_result”,“pid”:“<0.10322.0>”,“line”:177}

{“time”:1744801652971049,“level”:“warning”,“msg”:“authentication_failure”,“clientid”:“12345”,“username”:“123”,“peername”:“172.27.175.51:59473”,“tag”:“AUTHN”,“reason”:“bad_username_or_password”,“pid”:“<0.10322.0>”}

{“time”:1744801652971081,“level”:“debug”,“msg”:“mqtt_packet_sent”,“clientid”:“12345”,“username”:“123”,“peername”:“172.27.175.51:59473”,“tag”:“MQTT”,“pid”:“<0.10322.0>”,“packet”:“CONNACK(Q0, R0, D0, AckFlags=0, ReasonCode=4)”,“line”:893}

{“time”:1744801652971502,“level”:“debug”,“msg”:“emqx_connection_terminated”,“clientid”:“12345”,“username”:“123”,“peername”:“172.27.175.51:59473”,“tag”:“SOCKET”,“reason”:“{shutdown,bad_username_or_password}”,“pid”:“<0.10322.0>”,“line”:661}

{“time”:1744801652971558,“level”:“info”,“msg”:“terminate”,“clientid”:“12345”,“username”:“123”,“peername”:“172.27.175.51:59473”,“reason”:“{shutdown,bad_username_or_password}”,“pid”:“<0.10322.0>”,“line”:666}

mysql连接时没问题的 我该用plain来配置的时候是能够通过认证的。

看了下代码,应该是那没问题的。
connect 时 password传的 password 是 123456 吧 ?

是的hex 过来解密的密码是123456

所以文档是不清楚的。
emqx取出salt来当成字符串直接转换为二进制。
我这里是随机盐转换成了16进制字符串或base64存入后,由于emqx不会解码所以导致了盐不一致。
SELECT
HEX(FROM_BASE64(password)) AS password_hash,
FROM_BASE64(salt) as salt,
tag AS is_superuser
FROM users
where id = ${username}
LIMIT 1

你的 salt 不需要 decode_hex

./bin/emqx eval 'Salt = <<"3be7fa3a552bbdb7055a8f6d08d6a966">>, HashBin = crypto:pbkdf2_hmac(sha256, <<"123456">>, Salt, 10000, 32), io:format("~s~n", [binary:encode_hex(HashBin, lowercase)]).'
da025987f7e6c0c56d64fcc5a2579031d78aa6d4e8037ee4945c5d6e26ff78df