Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:117075 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 9090 invoked from network); 20 Feb 2022 11:58:19 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Feb 2022 11:58:19 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D3E2A180088 for ; Sun, 20 Feb 2022 05:17:17 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS24940 176.9.0.0/16 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 20 Feb 2022 05:17:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1645363035; bh=dKK/gVC45eCzVdafRN+d+ljK21SvX+gBoSgv0LzWyJY=; h=Date:Subject:To:References:From:In-Reply-To:From; b=datTG2dE4uc9q4/fT7qwXVlPKgl3vnGG96slhE1dYA9fqR3gI2BsuQlak7b22n2Qa gthmdlIUvHO6RgB966WPKfJBbEjhff20EWgmRn3QU2PPxiPvVd5jBBQo4+OX5rFkgW swixdw0eUOnTktIQfS1tMBDKczYzUuAg08dNyVXdD0H/1K6i/H/LssVIReldR4KfQ4 3CGgBYvjTECPDwhH5BngUS3SYtgCq0DNba/FYNdU+0jkH8uh3e7Obfzaesa9XKOMAL iW+uOw6vcIszzoG9KGoBO7ae5qXxEMiuRb/9gI2xtw0mJt3Aw/7/d1gVBHr+SzgLjJ lkY3Tzg61utoA== Message-ID: <3c6871ca-589d-6812-800c-a3b9ad6bb575@bastelstu.be> Date: Sun, 20 Feb 2022 14:17:14 +0100 MIME-Version: 1.0 Content-Language: en-US To: steve@tobtu.com, Stanislav Malyshev , internals@lists.php.net References: <5983302.2649742.1645319015766@email.ionos.com> <6238bf00-011e-35cc-d84b-4082b4f05099@gmail.com> <497325306.1564942.1645357444018@email.ionos.com> In-Reply-To: <497325306.1564942.1645357444018@email.ionos.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] RFC proposal to deprecate crypt() From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=c3=bcsterhus?=) Hi Steve, On 2/20/22 12:44, steve@tobtu.com wrote: > Also ~99% of implementations of crypt() that use sha256crypt and/or sha512crypt password hashing algorithms are vulnerable to a long password DoS attack. Since they don't know they need to limit the password length because the runtime is O(pwLen^2+pwLen*rounds). Note a 14000 byte password takes ~1 second, 28000 is ~3 seconds, 56000 is ~11 seconds (results may vary depending on CPU and sha256crypt vs sha512crypt). Ignoring bcrypt: sha256crypt and sha512crypt are the only other algos that are not horrible and they are still very bad. > >>> Since password_verify() and password_needs_rehash() already supports hashes created with crypt(), the only thing needed to do is remove crypt(). >> >> Removing it would cause serious BC issues with no practical gain. > > What are "BC issues"?... Backward compatibility issues? Yes. > If that's the case, you may not know that password_verify() can verify all password hashes created by crypt(). The whole point of deprecating and finally removing crypt() is that users can no longer create bad password hashes. This is a massive gain in security. It's like removing mcrypt which removed people's ability to ECB encrypt data. Sure there are very limited uses that are secure but 99.9999% are crypto101 errors. I am maintaining a software that supports a *legacy* password hashing algorithm that, for reasons that are not relevant to this discussion, performs two passes of BCrypt hashing with the *same* salt: crypt(crypt('password', '$2a$08$salt'), '$2a$08$salt'); This is not something that can be replicated with password_hash and password_verify, because password_hash does not accept an explicit salt starting with PHP 8.0 and password_verify does not know about this double hashing. Even though this hashing algorithm is legacy, we need to maintain compatibility with that for the foreseeable future to be able to upgrade users into the current (password_hash() based) hashes, without them needing to reset their passwords. > Also the *ONLY* non-broken password hash function that crypt() can do is bcrypt and password_hash()/password_verify() is a better alternative for bcrypt hashes. > > Basically crypt() serves no purpose besides as a legacy footgun. > I disagree. Apart from my real world use case above, there might also be other real world use-cases where interoperability with other software is required. As an example: Older versions of Dovecot (< 2.3) do not necessarily support BCrypt hashes, but they support SHA512-CRYPT. The existence of the crypt() function allows a PHP-based management portal to generate password hashes that are understood by those Dovecot versions. Best regards Tim Düsterhus