Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broker does not accept PBKDF2_SHA512 digests that contain . character in them #2847

Closed
shantanoo-desai opened this issue Jul 10, 2023 · 1 comment

Comments

@shantanoo-desai
Copy link

shantanoo-desai commented Jul 10, 2023

Environment

  • Ubuntu 20.04 LTS Windows Subsystem for Linux 2 (WSL2) on Window 10
  • Running on docker
  • Eclipse Mosquitto environment: 2.0.15 / 2.0.15-openssl as a docker container

Problem

This seems to be a strange behavior where a PBKDF2_SHA512 digest generated from an external tool should in theory accept the password but the Broker rejects it particularly when it comes have . character in the digest.

Reproduction

I am using Python's passlib package which offers a simple wrapper over the PBKDF2_SHA512 HMAC logic using simple function APIs.

The package can simply be downloaded using pip install passlib on a system (current and stable version is 1.7.4)

Digest Generator Script

generator.py

from passlib.hash import pbkdf2_sha512

digest = pbkdf2_sha512.using(salt_size=12, rounds=101).hash('testing')

print(digest.replace('pbkdf2-sha512', '7') + '==')

the script replicates the logic of generating digest for a plain-text-password called: testing. It also sets the salt size of 12 and iteration rounds of 101 in order to comply with the Brokers decryption logic.

In order to generate simply execute:

python generator.py

Generating Digests

for the testing password I have generated some digest:

  • two with . in the digest:

    $7$101$sta69/5/D2GsdU5p$8xrtCMQiebVOFT5TDUKMq3th4u5LLv6qiMsyINBVUy6rfc4w44.RxymGV3XUEfFJPLr7FtNLI4eAlb8Vd.uxKg==
    $7$101$KSWkFGLMmVMKwTgn$bosSxDO8kezBvTqmFqFUl6BY.MM8PVBeFxhwRpITRFmH06nfjIOi6B.KwH0nm26MTjhREbDRlKmPG92g6bf5DQ==
    
  • one without . in the digest:

    $7$101$vpeSMgaAsNYao7RW$uCbl8b3Efn4Oo9TGiIGm9pE/c8uBCSvrrcUD4KvHrEPNg7Wg9L38p6N9rUHO04jKO6D88AWnS2FRbcqbF05AGw==
    

Broker's users file

add the hashed passwords in a users file as follows:

withdot1:$7$101$sta69/5/D2GsdU5p$8xrtCMQiebVOFT5TDUKMq3th4u5LLv6qiMsyINBVUy6rfc4w44.RxymGV3XUEfFJPLr7FtNLI4eAlb8Vd.uxKg==
withdot2:$7$101$KSWkFGLMmVMKwTgn$bosSxDO8kezBvTqmFqFUl6BY.MM8PVBeFxhwRpITRFmH06nfjIOi6B.KwH0nm26MTjhREbDRlKmPG92g6bf5DQ==
withoutdot:$7$101$vpeSMgaAsNYao7RW$uCbl8b3Efn4Oo9TGiIGm9pE/c8uBCSvrrcUD4KvHrEPNg7Wg9L38p6N9rUHO04jKO6D88AWnS2FRbcqbF05AGw==

Broker's conf file

listener 1883
protocol mqtt

allow_anonymous false
password_file /mosquitto/config/passwd

log_type all

Spin a Docker container

docker run --rm -u $(id -u):$(id -g)  -p 1883:1883 \
  -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro \
  -v ./users:/mosquitto/config/passwd \
  eclipse-mosquitto:2.0.15

Broker Output logs

1688982627: mosquitto version 2.0.15 starting
1688982627: Config loaded from /mosquitto/config/mosquitto.conf.
1688982627: Error: Unable to decode password for user withdot1, removing entry.
1688982627: Error: Unable to decode password for user withdot2, removing entry.
1688982627: Opening ipv4 listen socket on port 1883.
1688982627: Opening ipv6 listen socket on port 1883.
1688982627: mosquitto version 2.0.15 running

Results

As observed any digests with . character in them are thrown out and only digests without them are accepted by the broker. This is also checked via connecting to the broker the with credentials below in the GIF.

mosquitto-user-hmac-error

@shantanoo-desai
Copy link
Author

shantanoo-desai commented Jul 11, 2023

Solution

As mentioned by Roger Light in the Mailing List, it turns out that when using passlib it performs a different Base64 encoding

The adapted solution for the generator.py:

from passlib.hash import pbkdf2_sha512

digest = pbkdf2_sha512.using(salt_size=12, rounds=101).hash('testing')

if '.' in digest:
  print("shortened Base64 detected")
digest = digest.replace('pbkdf2-sha512', '7').replace('.', '+') + '=='

print(digest)

Tests

Generating two digests (one including . replaced by + and other without .)

withoutdot:$7$101$V0pprXWulbJ2jhGi$vS6eNY1hFU8Uh8C3SM142i7zhOWmfyClP45LeQXq1ltmzepp4G5GMLuESxR8b4OrtYG+jsWVssbgr3USUVHIjg==
withdot:$7$101$xNg7h/Ae49y7N0ao$mnkVPhMcxglKn+3/V7irjd3EEt9BFECt3uTjMWZ4znpaY0ffX1909+OtIjpZfbOHBvY44WZoVxt4VdPiwNhhVQ==

the broker accepts the credentials

1689058823: mosquitto version 2.0.15 starting
1689058823: Config loaded from /mosquitto/config/mosquitto.conf.
1689058823: Opening ipv4 listen socket on port 1883.
1689058823: Opening ipv6 listen socket on port 1883.
1689058823: mosquitto version 2.0.15 running

And one is able to connect to the broker withdot and withoutdot credentials for the password testing

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant