Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:75674 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 8689 invoked from network); 17 Jul 2014 19:38:29 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Jul 2014 19:38:29 -0000 Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.177 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.220.177 mail-vc0-f177.google.com Received: from [209.85.220.177] ([209.85.220.177:60729] helo=mail-vc0-f177.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 47/F2-18859-23628C35 for ; Thu, 17 Jul 2014 15:38:27 -0400 Received: by mail-vc0-f177.google.com with SMTP id hy4so5429685vcb.22 for ; Thu, 17 Jul 2014 12:38:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=GIu5MQqnUIH0gsVsk99+EYV7IVyMheW+2cBuhZWyoew=; b=WwhDuigw3hB+/bcnncZn46YWaF/or4+OKooPPk1VQ5FDMsVRJ3fDw4WleK5k5JRTu0 +68QI78+QROXb3z9A3fmAo+ZFkiAqOKQ4tP8EFpeftPc3ybf2co4ixCVlttjzuwSERO7 kOzros3SWxO1rFWJUhYS7yQqRgWNhasd9/FgYlyZsWX3QszrZhLishJjee1Aec3NFfkk u3vGihk/4rS2B5Pei29o+48E1hfDelOi1sAN4eHq6KvjJ15ZjsxC95ajkaU8r927XaKM DexSw1bfStYpVnOTKz0UwCW+6xCssa9AVhamuAo6nOzbVeKM7ETK2lJUUqy5p0A5tdDJ Cafw== MIME-Version: 1.0 X-Received: by 10.220.5.138 with SMTP id 10mr15736726vcv.67.1405625904031; Thu, 17 Jul 2014 12:38:24 -0700 (PDT) Received: by 10.58.45.137 with HTTP; Thu, 17 Jul 2014 12:38:23 -0700 (PDT) In-Reply-To: References: Date: Thu, 17 Jul 2014 15:38:23 -0400 Message-ID: To: Adam Harvey Cc: Tjerk Meesters , Yasuo Ohgaki , Sara Golemon , "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] crypt() BC issue From: ircmaxell@gmail.com (Anthony Ferrara) All, Look at the issue, there's a line in there that is the crux of the issue: > So problem isn't only in ROUNDS_MIN. In fact, the overall algorithm changed. Look at a quick example: http://3v4l.org/Eov3o From 5.3.2+ (when we pulled in our own implementation of crypt-sha256 and crypt-sha512, and crypt-blowfish): using salt: string(31) "$6$rounds=3D1000$abcdefghijklmnop" gives hash: string(118) "$6$rounds=3D1000$abcdefghijklmnop$SgL/Atu7DClkX0qBUuG6FS2bRf2X= mLFWY9b8pRttPEj9ZSh4MKE5bKlz4WAKomLuWI.YQ5oIPLO2L.0OioAeW/" great. But in 4.3.0 - 5.2.17: the same salt gives: string(99) "$6$rounds=3D10$EdPD9pXG2vAIeeyG2E/9Mzey2mA/qZgIBAbccXWtrNiymhFY= XNK4r2gphMi4KOksXRubHnBWGVh/p2pP2D3R.." Which is shorter. Also note that the rounds went from the defined 1000, to = 10. Things get far weirder: http://3v4l.org/KZoIv $h1=3D'$6$rounds=3D1$abcdefghijklmnop'; $h2=3D'$6$abcdefghijklmnop'; gives us (on 4.3.0 - 5.2.17): string(102) "$6$rounds=3D1000$$6TFP.7u1vZP5A9fccvmUPteI8f29BLhgfqL1XEQqcrvq= TSKKw5SBa2qw1sOwLEQ41Dhl1u/Jbi2hRHRYCdxuv0" string(99) "$6$abcdefghi$4Dv/xQG4euniWsyrRHGUrNqM9CFl5Pg9EI88OgO4tIzuV952Jn= T09wVxrzUP9l/dr0wP3YSs1Ufz1qJpifLAA0" Note that these are different all around from the other results from the same version range. Basically, the version of crypt being linked to is either buggy (not likely) or our documentation of it is (likely). And our implementation (since 5.3.2) conforms to our documentation instead of the old behavior. Considering 5.3.2 was released 4 years ago, and 5.2 has been EOL for 3.5 years, I don't think there's anything that can be done about this. If it was a simple limit that needed changing, a polyfill would be easy (took me 10 minutes: https://gist.github.com/ircmaxell/ac0710ce044504f65cf0 ). But seeing the entire algorithm is different, much harder. I think this should be documented, and then called a day. I don't see anything else that could reasonably be done (changing crypt() at this point is out of the question IMHO). > - Add bool crypt_migration INI that is default to OFF for PHP 5.4 and up= . > - master will not have this INI. Please don't. As I showed above, it's already long past that point. And we don't need new ini settings. And what that ini setting would control is not the minimum iteration flag (as that's not the only problem), but which version of libcrypt we're binding to (our internal one, or an external one). Which means that the overall behavior *will* change. And unless you do it perfectly, it could effect all of crypts algorithms (potentially impacting password_hash, etc). We internalized the algorithms in 5.3.2 at least partially because the system provided libraries were inconsistent at best (hence why many but not all 5.2 systems don't support bcrypt, it depended on the build of libcrypt you linked against). Please don't make us re-live this inconsistency... Especially when it won't really solve the problem. Regarding password_verify() accepting crypt(), I consider it an implementation detail that it works. I know the RFC specifies it, but it specifies it not as a conceptual fact (that it will always be no more than a reason to be there), but more as an explanation for what it's currently doing. I would not rely on that fact. It may work today. It may work tomorrow, but it shouldn't be documented as such (as it's the complement of password_hash(), not the complement of crypt()). > As far as I'm aware, the only reason for not marking crypt() > E_DEPRECATED right now is for compatibility with external systems, and > as far as those go, changing a default won't effect anything. I want to reinforce that point, because it's spot on the money: I think crypt should live on. password_hash should be the way new systems are built, sure. But as you mention external systems, crypt should be a standard way of interacting with them (heck, that's what the lib was designed for). It shouldn't be a "if you're not using password_hash(), you're doing it wrong". It's "password_hash() should solve the majority of use-cases, but if you have a different need, there are other options". My $0.02 Anthony On Thu, Jul 17, 2014 at 1:50 PM, Adam Harvey wrote: > On 16 July 2014 23:16, Tjerk Meesters wrote: >> On Thu, Jul 17, 2014 at 10:25 AM, Yasuo Ohgaki wrot= e: >> >>> Hi Tjerk, >>> >>> On Thu, Jul 17, 2014 at 11:09 AM, Tjerk Meesters >> > wrote: >>> >>>> Why should `password_verify()` work on a hash that wasn't generated wi= th >>>> `password_hash()`? The fact that it uses `crypt()` internally should n= ot >>>> leak outside of its API, imho. >>> >>> >>> password_*() is designed as crypt() wrapper and this fact is documented >>> since it was released. >>> >>> Obsolete password hash is easy to verify with password_needs_rehash(). >>> Developers can check password database easily with password_needs_rehas= h(). >>> >> >> The documentation states that the `hash` argument to both >> `password_needs_rehash()` and `password_verify()` is: >> >> hash - A hash created by password_hash(). > > Whoa. Don't put too much stock in that =E2=80=94 I think I made that up o= ut of > whole cloth while trying to get _something_ into the manual for one of > the early alpha releases of 5.5, and it wasn't intended as a > restrictive statement. > >> Passing a value from your own crypt() implementation may work, but that >> shouldn't be relied upon. I certainly wouldn't classify it as a problem >> that should be fixed in the password api. > > The original RFC specified that both crypt() and password_hash() > hashes were accepted here, and that's probably what the documentation > should say too. > > Adam > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >