Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98276 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 34882 invoked from network); 10 Feb 2017 02:37:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Feb 2017 02:37:57 -0000 Authentication-Results: pb1.pair.com header.from=yohgaki@ohgaki.net; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=yohgaki@ohgaki.net; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ohgaki.net designates 180.42.98.130 as permitted sender) X-PHP-List-Original-Sender: yohgaki@ohgaki.net X-Host-Fingerprint: 180.42.98.130 ns1.es-i.jp Received: from [180.42.98.130] ([180.42.98.130:43824] helo=es-i.jp) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C0/BA-33872-3872D985 for ; Thu, 09 Feb 2017 21:37:57 -0500 Received: (qmail 101929 invoked by uid 89); 10 Feb 2017 02:37:51 -0000 Received: from unknown (HELO mail-qt0-f175.google.com) (yohgaki@ohgaki.net@209.85.216.175) by 0 with ESMTPA; 10 Feb 2017 02:37:51 -0000 Received: by mail-qt0-f175.google.com with SMTP id v23so22881754qtb.0 for ; Thu, 09 Feb 2017 18:37:51 -0800 (PST) X-Gm-Message-State: AMke39lG7mT3Nk9nRJVOo9cqpP0zxLhf0XZDY5Ow8J4myxcOyV70F28NZwg6vnxM+jXlLCpH4/F4U+XX31+rPQ== X-Received: by 10.200.43.115 with SMTP id 48mr6468989qtv.157.1486694264663; Thu, 09 Feb 2017 18:37:44 -0800 (PST) MIME-Version: 1.0 Received: by 10.140.19.232 with HTTP; Thu, 9 Feb 2017 18:37:04 -0800 (PST) In-Reply-To: References: Date: Fri, 10 Feb 2017 11:37:04 +0900 X-Gmail-Original-Message-ID: Message-ID: To: Scott Arciszewski Cc: Andrey Andreev , "internals@lists.php.net" Content-Type: multipart/alternative; boundary=001a113f443488fcc5054823fb03 Subject: Re: [PHP-DEV] hash_hkdf() signature From: yohgaki@ohgaki.net (Yasuo Ohgaki) --001a113f443488fcc5054823fb03 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Scott and all, On Thu, Feb 9, 2017 at 10:52 PM, Scott Arciszewski wrote: > > =E2=80=8B >> =E2=80=8BHKDF relies on PRK being cryptographically strong. >> =E2=80=8B >> =E2=80=8B > > > > =E2=80=8BYes, b=E2=80=8But not for the reasons you might suspect. > > =E2=80=8BThe main use case of HKDF is to completely prevent related-key a= ttacks, > while splitting a single key into several for domain-specific purposes.= =E2=80=8B > Figuring out a subkey (by sheer luck) should also not give an attacker > enough information to recreate the IKM. > > HKDF isn't meant for key stretching (e.g. use an 80-bit secret in an > application that requires a 256-bit secret). That's what a password hashi= ng > function is for. (Bcrypt, Argon2, etc.) > > =E2=80=8B >> =E2=80=8BYou should understand users _must_ make sure either "salt" or "= IKM" is > > strong for HKDF to work. Since hash_hkdf() is generic function, you never > > can make sure IKM to be strong always.=E2=80=8B > > =E2=80=8B=E2=80=8B > > Not quite. IKM has to be strong. The salt? Not so much. > > In cryptography protocols, salts are considered public information (even > if you don't go out of your way to publish it). > > If you have a weak IKM but a strong salt (32 bytes from random_bytes()), > you should still consider the OKM weak. > =E2=80=8B > >> Salt is the most important for both input and output key security. >> Salt is mandatory and/or can be used for almost always with PHP. >> Salt usage results in better design/security. >> Salt is often used as final key as combined key. > > > > Don't get me wrong: Having secure random salts is useful (serves as a > useful way to enlarge the effective nonce in a symmetric encryption > protocol). > > But the cryptographic secret in this protocol is IKM. Not the salt. > I agree that your description matches many typical crypto encryptions/authentication/etc. As you would know, there are some exceptions that encryption key is not really a random (Not cryptographically strong) If user could use strong IKM, they should use it, then salt could be for additional security. (HKDF IKM could be weak, salt could be secret, but you mentioned typical use case and best practice in crypto) The most typical HKDF application with PHP is access token key derivations with timestamp such as CSRF and Object Access token. For these applications, salt usage is strongly recommended, info(context) is recommended, length is OK with hash default. e.g. Generating CSRF token keys $expire =3D time()+900; // Even, non secret, low entropy salt makes HKDF OK= M significantly stronger. $csrf_token =3D bin2hex(hash_hkdf('sha256', $_SESSION['CSRF_TOKEN_SEED'], 0= , '', $expire)); then, send $expire and $csrf_token as access key. This could be done with hash_hmac() already. $csrf_token =3D hash_hmac('sha256', $_SESSION['CSRF_TOKEN_SEED'], $expire))= ; What's really good about HKDF is it can add additional non secret optional context(domain) safely, as you mentioned. // Make CSRF token only valid to 'Admin' features. $csrf_token =3D bin2hex(hash_hkdf('sha256', $_SESSION['CSRF_TOKEN_SEED'], 0= , 'Admin', $expire)); // Should be OK, but this is risky compare to above. $csrf_token =3D hash_hmac('sha256', $_SESSION['CSRF_TOKEN_SEED'], $expire. '-Admin')); Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net --001a113f443488fcc5054823fb03--