• Modern encryption for INN's ckpasswd or equivalent options?

    From Jesse Rehmer@21:1/5 to All on Sat Jan 28 19:11:59 2023
    Does anyone have an example perl_auth program I could reference that supports more modern encrypted storage of passwords?

    I have a small set of users and do not want to use PAM or system auth. The crypt implementation used by ckpasswd -f, is, well, extremely old.

    Cheers,

    Jesse Rehmer

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Russ Allbery@21:1/5 to Jesse Rehmer on Sat Jan 28 11:59:27 2023
    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> writes:

    How can I tell what algorithms my library supports?

    man 3 crypt should hopefully tell you what the available hash algorithms
    are. You'll need something that writes the password file, though (or use passwd to set a password for a system user and then copy and paste the
    hash from /etc/shadow, which I've done in a pinch).

    https://man.freebsd.org/cgi/man.cgi?crypt(3) seems to imply nothing better
    than SHA-512 is supported, which is a bit surprising.

    --
    Russ Allbery (eagle@eyrie.org) <https://www.eyrie.org/~eagle/>

    Please post questions rather than mailing me directly.
    <https://www.eyrie.org/~eagle/faqs/questions.html> explains why.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Russ Allbery@21:1/5 to Jesse Rehmer on Sat Jan 28 11:23:22 2023
    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> writes:

    Does anyone have an example perl_auth program I could reference that
    supports more modern encrypted storage of passwords?

    I have a small set of users and do not want to use PAM or system
    auth. The crypt implementation used by ckpasswd -f, is, well, extremely
    old.

    ckpasswd -f just uses crypt, so it will use as modern of a password
    hashing algorithm as your libc or libcrypt supports. Generally this is configured by the prefix of the hashed password. For example, on Linux,
    you can use hashes starting with $y$ to use yescrypt, which is about as
    modern as you could possibly want.

    This is therefore entirely up to how you set the passwords in the file
    that you're pointing to with ckpasswd -f, which is a bit outside what INN
    deals with. It's quite possible that htpasswd, for example, won't
    generate one of the newer hash types.

    --
    Russ Allbery (eagle@eyrie.org) <https://www.eyrie.org/~eagle/>

    Please post questions rather than mailing me directly.
    <https://www.eyrie.org/~eagle/faqs/questions.html> explains why.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesse Rehmer@21:1/5 to Russ Allbery on Sat Jan 28 19:40:44 2023
    On Jan 28, 2023 at 1:23:22 PM CST, "Russ Allbery" <eagle@eyrie.org> wrote:

    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> writes:

    Does anyone have an example perl_auth program I could reference that
    supports more modern encrypted storage of passwords?

    I have a small set of users and do not want to use PAM or system
    auth. The crypt implementation used by ckpasswd -f, is, well, extremely
    old.

    ckpasswd -f just uses crypt, so it will use as modern of a password
    hashing algorithm as your libc or libcrypt supports. Generally this is configured by the prefix of the hashed password. For example, on Linux,
    you can use hashes starting with $y$ to use yescrypt, which is about as modern as you could possibly want.

    This is therefore entirely up to how you set the passwords in the file
    that you're pointing to with ckpasswd -f, which is a bit outside what INN deals with. It's quite possible that htpasswd, for example, won't
    generate one of the newer hash types.

    How can I tell what algorithms my library supports? I'm on FreeBSD 13 and in the past was on Linux. I could never get ckpasswd to accept anything more than "htpasswd -d" outputs, which on all of the operating sytems I've used outputs the weakest possible encryption:

    -d Use crypt() encryption for passwords. This is not supported by
    the httpd server on Windows and Netware. This algorithm limits
    the password length to 8 characters. This algorithm is insecure
    by today's standards. It used to be the default algorithm until
    version 2.2.17.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesse Rehmer@21:1/5 to Russ Allbery on Sat Jan 28 20:27:57 2023
    On Jan 28, 2023 at 1:59:27 PM CST, "Russ Allbery" <eagle@eyrie.org> wrote:

    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> writes:

    How can I tell what algorithms my library supports?

    man 3 crypt should hopefully tell you what the available hash algorithms
    are. You'll need something that writes the password file, though (or use passwd to set a password for a system user and then copy and paste the
    hash from /etc/shadow, which I've done in a pinch).

    https://man.freebsd.org/cgi/man.cgi?crypt(3) seems to imply nothing better than SHA-512 is supported, which is a bit surprising.

    It also says it supports MD5, but that's what I was trying to use without success. I'll bang away and a few different ways to generate different hashes and give it another stab.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesse Rehmer@21:1/5 to Russ Allbery on Sun Jan 29 04:46:19 2023
    On Jan 28, 2023 at 1:59:27 PM CST, "Russ Allbery" <eagle@eyrie.org> wrote:

    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> writes:

    How can I tell what algorithms my library supports?

    man 3 crypt should hopefully tell you what the available hash algorithms
    are. You'll need something that writes the password file, though (or use passwd to set a password for a system user and then copy and paste the
    hash from /etc/shadow, which I've done in a pinch).

    https://man.freebsd.org/cgi/man.cgi?crypt(3) seems to imply nothing better than SHA-512 is supported, which is a bit surprising.

    Auth works if I use the following for MD5:

    openssl passwd -1 -salt xyz somepassword

    Or the following for SHA512:

    openssl passwd -6 -salt xyz somepassword

    The hashes from "htpasswd -B" work as well. I suppose the MD5 implementation for htpasswd has some oddities as I cannot get that to work, but using openssl is just fine.

    Cheers,

    Jesse

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Garrett Wollman@21:1/5 to jesse.rehmer@blueworldhosting.com on Sun Jan 29 19:56:14 2023
    In article <tr4tmr$224f$1@nnrp.usenet.blueworldhosting.com>,
    Jesse Rehmer <jesse.rehmer@blueworldhosting.com> wrote:
    Auth works if I use the following for MD5:

    openssl passwd -1 -salt xyz somepassword

    Or the following for SHA512:

    openssl passwd -6 -salt xyz somepassword

    Note that the salt, to serve its function, should be randomly generated
    and unique for each user. The openssl passwd command will do that for
    you if you simply leave out the `-salt` option. The `-salt` option
    should only be used when you are *verifying* a password.

    -GAWollman

    --
    Garrett A. Wollman | "Act to avoid constraining the future; if you can, wollman@bimajority.org| act to remove constraint from the future. This is Opinions not shared by| a thing you can do, are able to do, to do together."
    my employers. | - Graydon Saunders, _A Succession of Bad Days_ (2015)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Julien_=c3=89LIE?=@21:1/5 to All on Sat Feb 4 11:14:21 2023
    Hi Jesse and Russ,

    Thanks for this discussion, it was pretty interesting.

    How can I tell what algorithms my library supports?

    man 3 crypt should hopefully tell you what the available hash algorithms
    are.

    "man 3 crypt" does not indicate the available hash schemes on my system (Debian bullseye).
    Looking at the libcrypt-dev package which provides it, I see it installs both crypt.3 and crypt.5 man pages. The source package is libxcrypt even though it is libcrypt-dev (and not libxcrypt-dev).
    Available hash schemes are found in "man 5 crypt" in Debian (but "man 3 crypt" in FreeBSD).



    https://man.freebsd.org/cgi/man.cgi?crypt(3) seems to imply nothing better >> than SHA-512 is supported, which is a bit surprising.

    I confirm that on FreeBSD 13, the Perl crypt() function which uses the system crypt(3) one does not recognize yescript.



    Auth works if I use the following for MD5:

    openssl passwd -1 -salt xyz somepassword

    Or the following for SHA512:

    openssl passwd -6 -salt xyz somepassword

    I'll remove the mention of htpasswd from the ckpasswd man page, and modernize the wording.
    Here is what I came up with. I hope it will be of help for other people looking at how to generate passwords.

    -f filename
    Read passwords from the given file rather than using getpwnam(3).
    Each line of the file should look something like:

    username:$5$Hlb2yXPd$2nOO/QR9P1mnRFr/i6L9ybxbgSDXd4UlatKqbcY4eoB
    joe:FCjOJnpOo50IE:Old weak hash algorithm used for Joe

    Each line has at least two fields separated by a colon. The first
    field contains the username; the second field contains a password
    hashed with the crypt(3) function. Additional colons and data may
    appear after the encrypted password; that data will be ignored by
    ckpasswd. Lines starting with a number sign ("#") are ignored.

    INN does not come with a utility to create the encrypted passwords,
    but OpenSSL can do so and it's also a quick job with Perl (see the
    one-line example script below).

    A line in *filename* for the user "user" with the password "pass"
    would be "user:" followed with the output of the following command
    using SHA-256 as hashing scheme:

    % openssl passwd -5 pass
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    See the openssl-passwd(1) man page for the list of hashing schemes
    it can generate. You must take one that your system crypt(3)
    function handles (type "man 3 crypt" or "man 5 crypt" to find the
    supported hashing schemes).

    In case OpenSSL is not installed on your server, you can also use
    the following Perl command which does the same job:

    % perl -le "print crypt('pass', '\$5\$UIhtJSBOaC0Ap3Vk\$');"
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    As Perl makes use of crypt(3), you have access to all available
    hashing schemes on your systems (like yescript, if supported). Make
    sure to use a random salt.

    % perl -le "print crypt('pass', '\$y\$j9T\$YourSalt\$');"
    $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A

    --
    Julien ÉLIE

    « Le sel de l'existence est essentiellement dans le poivre qu'on y
    met. » (Alphonse Allais)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Matija Nalis@21:1/5 to iulius@nom-de-mon-site.com.invalid on Sat Feb 4 14:06:34 2023
    On Sat, 4 Feb 2023 11:14:21 +0100, Julien ÉLIE <iulius@nom-de-mon-site.com.invalid> wrote:
    In case OpenSSL is not installed on your server, you can also use
    the following Perl command which does the same job:

    % perl -le "print crypt('pass', '\$5\$UIhtJSBOaC0Ap3Vk\$');"
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    As Perl makes use of crypt(3), you have access to all available
    hashing schemes on your systems (like yescript, if supported). Make
    sure to use a random salt.

    % perl -le "print crypt('pass', '\$y\$j9T\$YourSalt\$');"
    $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A


    For perl however, it is not really clear to beginners) what is the salt
    which must be changed/RANDOM, and what are the fixed elements, especially as one example users random string, and another human-readable version. (and yescript example having extra unexplained paramtered 'j9T')

    I'd suggest:

    - changing actual salt in *both* perl examples to "YourRandomSalt"
    - clarifiying in documentation that only "pass" (your password) and
    "YourRandomSalt" (random string which should be different for EACH
    user) parts of the commands should be changed, and all the rest be left
    as-is.


    --
    Opinions above are GNU-copylefted.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesse Rehmer@21:1/5 to iulius@nom-de-mon-site.com.invalid on Sat Feb 4 16:31:49 2023
    On Feb 4, 2023 at 4:14:21 AM CST, "Julien ÉLIE" <iulius@nom-de-mon-site.com.invalid> wrote:

    Hi Jesse and Russ,

    Thanks for this discussion, it was pretty interesting.

    I'll remove the mention of htpasswd from the ckpasswd man page, and modernize the wording.
    Here is what I came up with. I hope it will be of help for other people looking at how to generate passwords.

    -f filename
    Read passwords from the given file rather than using getpwnam(3).
    Each line of the file should look something like:

    username:$5$Hlb2yXPd$2nOO/QR9P1mnRFr/i6L9ybxbgSDXd4UlatKqbcY4eoB
    joe:FCjOJnpOo50IE:Old weak hash algorithm used for Joe

    Each line has at least two fields separated by a colon. The first
    field contains the username; the second field contains a password
    hashed with the crypt(3) function. Additional colons and data may
    appear after the encrypted password; that data will be ignored by
    ckpasswd. Lines starting with a number sign ("#") are ignored.

    INN does not come with a utility to create the encrypted passwords,
    but OpenSSL can do so and it's also a quick job with Perl (see the
    one-line example script below).

    A line in *filename* for the user "user" with the password "pass"
    would be "user:" followed with the output of the following command
    using SHA-256 as hashing scheme:

    % openssl passwd -5 pass
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    See the openssl-passwd(1) man page for the list of hashing schemes
    it can generate. You must take one that your system crypt(3)
    function handles (type "man 3 crypt" or "man 5 crypt" to find the
    supported hashing schemes).

    In case OpenSSL is not installed on your server, you can also use
    the following Perl command which does the same job:

    % perl -le "print crypt('pass', '\$5\$UIhtJSBOaC0Ap3Vk\$');"
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    As Perl makes use of crypt(3), you have access to all available
    hashing schemes on your systems (like yescript, if supported). Make
    sure to use a random salt.

    % perl -le "print crypt('pass', '\$y\$j9T\$YourSalt\$');"
    $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A

    This is a great explanation, maybe also take Matija's response into consideration for completeness.

    Where I got tripped up was using "htpasswd -m", which according to its man
    page produces MD5 hashes so I assumed it would work, but the output wasn't working with nnrpd, so I thought it had to be a deeper issue with crypto libraries/support.

    Thanks everyone!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Russ Allbery@21:1/5 to iulius@nom-de-mon-site.com.invalid on Sat Feb 4 09:20:42 2023
    Julien ÉLIE <iulius@nom-de-mon-site.com.invalid> writes:

    In case OpenSSL is not installed on your server, you can also use
    the following Perl command which does the same job:

    % perl -le "print crypt('pass', '\$5\$UIhtJSBOaC0Ap3Vk\$');"
    $5$UIhtJSBOaC0Ap3Vk$nbKgmykshoQ2HmvA3s/nI.X4uhhNHBKTYhBS3pYLjJ6

    As Perl makes use of crypt(3), you have access to all available
    hashing schemes on your systems (like yescript, if supported). Make
    sure to use a random salt.

    % perl -le "print crypt('pass', '\$y\$j9T\$YourSalt\$');"
    $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A

    Minor Perl syntax nit to avoid the backslashes:

    % perl -le 'print crypt("pass", q{$5$YourSalt$})' $5$YourSalt$V5hqwFg1nhKb5as6md9KTe5b2NyavsMS6dBYVKfp5W7

    % perl -le 'print crypt("pass", q{$y$j9T$YourSalt$})' $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A

    It may be worth mentioning that the opaque "j9T" string in the yescrypt
    example is generated with crypt_gensalt(3), and what parameters generated
    it. (I'm not sure if Perl has an easy interface to that.)

    --
    Russ Allbery (eagle@eyrie.org) <https://www.eyrie.org/~eagle/>

    Please post questions rather than mailing me directly.
    <https://www.eyrie.org/~eagle/faqs/questions.html> explains why.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Julien_=c3=89LIE?=@21:1/5 to All on Sun Feb 5 10:40:51 2023
    Hi all,

    [Jesse]
    Where I got tripped up was using "htpasswd -m", which according to
    its man page produces MD5 hashes so I assumed it would work, but the
    output wasn't working with nnrpd, so I thought it had to be a deeper
    issue with crypto> libraries/support.
    Thanks for having raised the possible problem. At least it permitted modernizing the documentation for ckpasswd.



    [Russ]
    Minor Perl syntax nit to avoid the backslashes:

    % perl -le 'print crypt("pass", q{$5$YourSalt$})' > $5$YourSalt$V5hqwFg1nhKb5as6md9KTe5b2NyavsMS6dBYVKfp5W7
    Yes, it's more readable this way, thanks!


    It may be worth mentioning that the opaque "j9T" string in the
    yescrypt example is generated with crypt_gensalt(3), and what
    parameters generated it. (I'm not sure if Perl has an easy interface
    to that.)
    OK. I also did not find in CPAN a module dealing with yescript or more generally with crypt options.



    [Matija]
    For perl however, it is not really clear to beginners) what is the salt
    which must be changed/RANDOM, and what are the fixed elements, especially as one example users random string, and another human-readable version. (and yescript example having extra unexplained paramtered 'j9T')

    OK, I'll see how to explain it better.


    I'd suggest:

    - changing actual salt in *both* perl examples to "YourRandomSalt"

    The subtlety is that yescript expects a salt whose length is multiple of
    4... I'll keep "YourSalt" and mention your second point:

    - clarifiying in documentation that only "pass" (your password) and
    "YourRandomSalt" (random string which should be different for EACH
    user) parts of the commands should be changed, and all the rest be left
    as-is.

    New wording which I hope contains all the details :)


    In case OpenSSL is not installed on your server, you can also use
    the following Perl command which does the same job:

    % perl -le 'print crypt("pass", q{$5$YourSalt$})'
    $5$YourSalt$V5hqwFg1nhKb5as6md9KTe5b2NyavsMS6dBYVKfp5W7

    As Perl makes use of crypt(3), you have access to all available
    hashing schemes on your systems. For instance, if yescript is
    supported, you can generate an encrypted password with an argument
    like "$y$j9T$YourSalt$" to Perl crypt function, where "y" is the
    prefix for yescript, "j9T" the parameters passed to
    crypt_gensalt(3)
    to generate the hashed password (these parameters control the
    yescript configuration, and correspond in this example to
    "YESCRYPT_DEFAULTS" flag, the recommended flavor which has "j"
    value
    in 2023, with 4096 as block count and 32 as block size) and
    "YourSalt" a string which should be chosen at random and different
    for each user. The syntax and optimal length of the salt
    depends of
    the hashing scheme (e.g. a length multiple of 4 for yescript) and
    cryptographic recommendations (e.g. at least 32 random bits in
    length, following NIST SP 800-63B recommendations in 2023).

    To put it in a nutshell, in the following command, you only have to
    change the password "pass" and the "YourSalt" random string,
    different for each user, and leave the rest of the command as-is:

    % perl -le 'print crypt("pass", q{$y$j9T$YourSalt$})'
    $y$j9T$YourSalt$X4tB48vKNDT6mK0vNOc7ppKPWvEsyMg5LwoQfO50r2A

    A random salt of 12 characters can be obtained with the following
    command (the result corresponds to 72 random bits as each character
    is selected in a 6-bit range of 64 possible characters):

    % perl -le 'print join("",
    (".", "/", 0..9, A..Z, a..z)[map {rand 64} (1..12)])'
    k2W/17eJu58r


    --
    Julien ÉLIE

    « Le rire est une chose sérieuse avec laquelle il ne faut pas
    plaisanter. » (Raymond Devos)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)