rfc1036 / whois

Intelligent WHOIS client
GNU General Public License v2.0
481 stars 113 forks source link

Wrong salt length: [0-9]+ bytes when 0 expected. #119

Open dragonxtek opened 1 year ago

dragonxtek commented 1 year ago

When I tried to generate a yescrypt hash with a salt I got this issue:

./mkpasswd -V | head -n1 mkpasswd 5.5.14 ./mkpasswd -S '0CbpG1oIS1UOftfSzI7eQ0' Wrong salt length: 22 bytes when 0 expected.

How can I generate a valid yescrypt hash using a specific salt?

rfc1036 commented 1 year ago

0 means that this is not supported. It is not completely trivial to pass the yescrypt salt to crypt(3) because generating the parameters string for it cannot be done by mkpasswd itself.

I cannot remember if there is a reasonable solution, but I welcome discussions on how to implement this.

Woi commented 1 year ago

As user I got confused by this behaviour as well and assumed a bug. Now that I know it's not, I'm curious:

Background: I'm looking for a way to use yescrypt over SHA-512 for password encryption in my Fedora kickstart files. I found https://github.com/besser82/libxcrypt/issues/64. Luckily mkpasswd is available in Fedora nowadays, but I encountered this not-a-bug. As far as I understand, mkpasswd can be build using libcrypt or the modern libxcrypt [1] but is using the first on Fedora [2]

[1] https://github.com/rfc1036/whois/blob/41b34352adea6ab366c25f36fb8f34cb62aeb153/mkpasswd.c#L38-L44

[2]

$ head -2 /etc/os-release 
NAME="Fedora Linux"
VERSION="37 (Thirty Seven)"

$ ldd /usr/bin/mkpasswd
    linux-vdso.so.1 (0x00007fffa07f1000)
    libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f9e3d381000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f9e3d1a4000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f9e3d3e3000)
tukusejssirs commented 1 year ago

In my case, the salt seems to be always j9T (the hash starts with $y$j9T$). I have tested this on Fedora 38 using mkpasswd -sm yescrypt <<< 'asdf' and using docker run --rm quay.io/coreos/mkpasswd -sm yescrypt <<< 'asdf' (based on the Fedora CoreOS docs).

I think using one salt only (of three-byte length) is less secure than providing a custom, possibly much longer salt.

rfc1036 commented 1 year ago

Because that's not the salt but the algorithm parameters. The salt is after it.

tukusejssirs commented 1 year ago

🤦‍♂️ You’re right! I have missed the dollar sign after it. Thanks!

Anyway, how would you verify a hash matches a particular password if you can’t provide the salt? 🤔 Using an expernal program?

mattpr commented 1 year ago

It is not completely trivial to pass the yescrypt salt to crypt(3) because generating the parameters string for it cannot be done by mkpasswd itself. I cannot remember if there is a reasonable solution, but I welcome discussions on how to implement this.

In the shadow file there is also the algorithm parameters bit (e.g. j9T in the below sample shadow entry for password foobar). So I guess the mkpasswd would need to support an additional CLI parameter for user to provide parameters for some methods. Or the -m param could be updated to support a new structure where parameters can be passed along with the method (e.g. yescrypt:j9T or $y$j9T$ or something).

testpw:$y$j9T$GlmttU6wcxDgSj5vHoHdd.$s62VqHooKXZKns1/eO.Qqn3Wh8PHyS5Ao71Dcyn0SgA:19599:0:99999:7:::

I only looked into this casually today, but found a couple helpful SO answers that cover some detail on generating the required parameters for scrypt ($7$) and yescrypt/scrypt-variable ($y$)...

...obviously that isn't a solution, but if I (or someone else) gets around to picking up fixing this...those might be a good point to start in terms of understanding what needs to be done.

Use case here is in devops environment where want to enforce setting passwords to certain values (automated) but do not want to set them over and over and over again...because we track number of changes made on each box as a metric. So need a method to check a known/expected password against shadow and then change or not change depending on whether it was already set. Currently we use mkpasswd for this which works fine for sha256/512 but not yescrypt which is the new default for shadow in lots of places.

(Yeah yeah yeah, normally we only use publickey and disallow remote password logins...or intentionally lock ourselves out of the boxes after provisioning...but sometimes we have a case where we can't avoid passwords.)