Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88879 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69612 invoked from network); 19 Oct 2015 19:43:55 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Oct 2015 19:43:55 -0000 Authentication-Results: pb1.pair.com header.from=scott@paragonie.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=scott@paragonie.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain paragonie.com from 209.85.217.177 cause and error) X-PHP-List-Original-Sender: scott@paragonie.com X-Host-Fingerprint: 209.85.217.177 mail-lb0-f177.google.com Received: from [209.85.217.177] ([209.85.217.177:32788] helo=mail-lb0-f177.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id DA/B1-54881-AF745265 for ; Mon, 19 Oct 2015 15:43:54 -0400 Received: by lbbpp2 with SMTP id pp2so126287283lbb.0 for ; Mon, 19 Oct 2015 12:43:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=dy4M9CBXhzc4ni89FSK40MPzw36bOlM8sGfibZ5W7vE=; b=bYZF/3MqttDK4rwVftMGkgPXaN+ukVbEjNjg8rg0zRLhvWYOpR8A/XUThmyiLKxhGy 3eC9jbezZ3N+5tVzXkcBKYXjM3vI2ExtJEOA5BKvSuRSJk8ekw/HQea4KhYlKNkekV1v kQ3mNyOXNWaTnhBpdCAQkxB8u9uuNCZ+j1etfdFgdWRVYvo4b8DUp0honVWN6SatzewP fwMjksrQGDMiUJqwnzbV6Lt31hKN/8No9MAN32xZU9dVou47QUpWAaL9OaFJJfSP+Zdv JTuvtdfRc2aHOWX28U7kOjN9nAUD3jZrPNPZiCZnOmfJnK+bamHPEtUeFie7/5PZYKUv FvPw== X-Gm-Message-State: ALoCoQlyHQ+I07q1Mx+S8OMq059hMqP58UTv/BYfydvAJ/KcPFyHYhY1qTr4tkDrIGjYmU+Eppj2 MIME-Version: 1.0 X-Received: by 10.112.168.194 with SMTP id zy2mr16124005lbb.79.1445283831510; Mon, 19 Oct 2015 12:43:51 -0700 (PDT) Received: by 10.114.161.18 with HTTP; Mon, 19 Oct 2015 12:43:51 -0700 (PDT) In-Reply-To: References: <56242DC5.7010306@gmail.com> <56250A9C.3050304@thefsb.org> Date: Mon, 19 Oct 2015 15:43:51 -0400 Message-ID: To: Chris Riley Cc: Tom Worster , =?UTF-8?B?w4FuZ2VsIEdvbnrDoWxleg==?= , Anthony Ferrara , "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Password_hash salt generation refactor From: scott@paragonie.com (Scott Arciszewski) On Mon, Oct 19, 2015 at 1:00 PM, Chris Riley wrote: > On 19 October 2015 at 16:22, Tom Worster wrote: > >> On 10/18/15 7:39 PM, =C3=81ngel Gonz=C3=A1lez wrote: >> >>> Korvin wrote: >>> >>>> +1 for 7.0.x security patch release, best effort sounds scary. >>>> >>> This is a salt. It doesn't need to be cryptographically secure. Using >>> php_rand() >>> there should pose no problem. >>> I would actually include that into the patch (move old lines 154-156 >>> into the >>> FAILURE if). >>> >> >> A password salt needs to be unique. It does not need to be drawn from a >> CSPRNG but that is one of the few ways we can be reasonably confident of >> uniqueness (since, as usual, we assume the platform RNG is properly seed= ed). >> > > > A password salt should not be predictable, allowing a salt to potentially > become predictable is a bad idea. Solution is to use a CSPRNG for > generation of salts. Hi all, I'd like to weigh in by quantifying the predictability of rand(). If you're well aware of statistics or versed in cryptography, you might be able to skip this email. (You might still want to read it to help verify or challenge my conclusion.) First, for the sake of generosity, let's assume that rand() is properly seeded, e.g. by 4 bytes from /dev/urandom, on each invocation so that the pid + time() issue doesn't come into play. (In reality, this is very important.) After seeding rand, there are 2^32 possible outputs. That's a little over 4 billion, and it's highly unlikely that your website has 4 billion user accounts with a hashed password, so that's good enough right? Well, not quite. For a moment, imagine you are in a room with 22 other people born in the same year as you. What is the probability that any two people in the room share the exact same birthday? Well, it turns out that the answer is 50%. We call this the Birthday Problem. From studying this problem, we can estimate the number of random samples to generate a collision from an n-bit keyspace by a simple formula: G =3D 2^(n/2). This is called the Birthday Bound. If you have a keyspace of 2^32 possible output sequences like we do from rand(), we can say that after 65,536 there is a 50% probability of finding at least one collision. It should go without saying, but if users have weak/common password choices and their salts collide, they will end up with duplicate bcrypt hashes. My conclusion is thus: Yes, we do need a CSPRNG here, especially if we want to encourage the use of the password_* API for any large system. https://en.wikipedia.org/wiki/Birthday_problem https://en.wikipedia.org/wiki/Birthday_attack http://eprint.iacr.org/2005/004 Scott Arciszewski Chief Development Officer Paragon Initiative Enterprises