Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:117074 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 4602 invoked from network); 20 Feb 2022 10:25:12 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Feb 2022 10:25:12 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 1F4F1180088 for ; Sun, 20 Feb 2022 03:44:09 -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=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS8560 74.208.0.0/16 X-Spam-Virus: No X-Envelope-From: Received: from mout.perfora.net (mout.perfora.net [74.208.4.194]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 20 Feb 2022 03:44:08 -0800 (PST) Received: from oxuslxaltgw03.schlund.de ([10.72.76.59]) by mrelay.perfora.net (mreueus004 [74.208.5.2]) with ESMTPSA (Nemesis) id 1MBVVT-1nXXPl1q1f-00Cvr9; Sun, 20 Feb 2022 12:44:06 +0100 Date: Sun, 20 Feb 2022 05:44:04 -0600 (CST) To: Stanislav Malyshev , internals@lists.php.net Message-ID: <497325306.1564942.1645357444018@email.ionos.com> In-Reply-To: <6238bf00-011e-35cc-d84b-4082b4f05099@gmail.com> References: <5983302.2649742.1645319015766@email.ionos.com> <6238bf00-011e-35cc-d84b-4082b4f05099@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Priority: 3 Importance: Normal X-Mailer: Open-Xchange Mailer v7.10.5-Rev38 X-Originating-Client: open-xchange-appsuite X-Provags-ID: V03:K1:uYnWSi2UUpOEr2RBTOwFLZKjn1XNFzx34g6f5GC+lmLOS83EPWr jUjyP+0MYb4dEtsPsvExg4/qFuJOejh9aU/6KQGNUFz/ja1d+D9zukNF3Ad23Dri02UTdAz lBXp9YLH2JGUYDvmr9YUIpr1enHuk42za06SADpLfLOYWcB8UT1ah7K9bsIr4m6yxl/QnMZ nR2GkMA9G9QkXNHo6LeLA== X-UI-Out-Filterresults: notjunk:1;V03:K0:umi67T3tovM=:eBr16dfCueAUHsSDYUJih6 bYEERwzncudMcYeksHndR8CZ7ZdiQ9wIfJYokRFIda7VK/z/+ZdJLU+Dz6rxrYAw2XHsFF94T UkV9O+3DG8+NRNDLYxH9TJR/HZpIxLNPLIJy+CeTuEDXWJ66svIAu35KKMin6NcGHwQ5F5QFQ QAksbRIxqe5lwJflqSC7CQJXOcd9IkIDSKi3Jm8rhE0wHyyL2Yfk2dKsCtkicDfUrFchHjsnG 9kl9AKV7BZkMsDNEd/kiFH5fjBsxb+qfMtCKmvVHxKW8bCkLyYEbn25ewYDS63n+gCLA+yQQG dTzV0U0cM3ogmI+WkwskK1CDwZ/nXi7Wvb3CeFpwbjEEA15BLct+4UkNlLttKC7zI4aZIwVVm p6XGuF7Ck5JtPMNtA+80e5gdqoEvDoDoVQHbD14PwUVTrTKVeL2iUAkytSUSgpHI0EE5OB3Ls C0O0ZFU30tBHp932S/Hk6aEZw2e93fyQDiZ6zemyJcfUbg46t8hLalTbdR5B+aaUOMBIdTjVt L0ExvWfKJq99r4aAgko1zTYZmXUB0ZT7YJ4KJEeX5/px2sOBrwWdoNqEameIs1geA2nulKPN0 99Bs2Ihk6FgjuFhJ87AmM6kt9/EN+7ZFD7XmP5COCnSA6m8QvunAvShtC7aGK2+d56+fEwRCi 7ldNwL8HPx+L5+y9nMzMb+/SRSIv8bhhKV2CqdobJWiqxLwAgvYLC7rp1HXXEjrhgUgE= Subject: Re: [PHP-DEV] RFC proposal to deprecate crypt() From: steve@tobtu.com > On 02/20/2022 1:10 AM Stanislav Malyshev wrote: > > > Hi! > > On 2/19/22 6:03 PM, steve@tobtu.com wrote: > > crypt() should be deprecate because it can be used to create bad password hashes: > > I don't think it's a good reason for deprecating functions. A lot of > functions, if used incorrectly, could produce bad results, it's not the > reason to not use them correctly. > Sorry, I really meant to say it can *only* create bad password hashes... and bcrypt which password_hash() is the preferred function to create a bcrypt hash. crypt() should be deprecated, unless there's a reason to let users write: $hash = crypt($password, "$2y$" . str_pad($cost, 2, "0", STR_PAD_LEFT) . strtr(base64_encode(random_bytes(16)), '+', '.')); // hi from 9 years ago https://www.php.net/manual/en/function.crypt.php#111086 (oof... ignore the minor errors and the update with random_bytes() because mcrypt was deprecated then removed) vs $hash = password_hash($password, PASSWORD_BCRYPT); Note the crypt() documentation: "password_hash() uses a strong hash, generates a strong salt, and applies proper rounds automatically. password_hash() is a simple crypt() wrapper and [password_verify() is] compatible with existing password hashes. Use of password_hash() is encouraged." That is the exact reason why mcrypt was deprecated: hard to use correctly and most uses of it were broken. 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? 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. 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.